Home > Net >  What is better for dict value assign a nonexistent key?
What is better for dict value assign a nonexistent key?

Time:07-08

Suppose that I want to add a value to a dict, but I'm not sure if the key exists. What would be the better way (performance matter)? If there is some better way...

my_dict['key'] = my_dict.get('key', new_value) # I like this!

OR

if 'key' not in my_dict:
    my_dict['key'] = new_value

CodePudding user response:

There's a built-in dict method for this:

my_dict.setdefault('key', new_value)

It returns the resulting value (i.e. the existing value if there was one, or the newly set one if there wasn't), which is useful in expressions like:

my_dict.setdefault('key', []).append('foo')

CodePudding user response:

Simply assign the new value like so:

my_dict['key'] = new_value

The old value, if exists, will be overwritten. If it does not exist, the key will be created and the new value will be assigned.

CodePudding user response:

you can use dis(Disassembler for Python bytecode) and check run-time. best approach base run-time and dis is if 'key' not in my_dict: my_dict['key'] = 'new_value', because first and second approaches have CALL_METHOD but third approach doesn't have CALL_METHOD. (Benchmark on colab)

my_dict = {i:i for i in range(10_000_000)}
%timeit my_dict['key'] = my_dict.get('key', 'new_value')
# 1000000 loops, best of 5: 123 ns per loop

%timeit my_dict.setdefault('key', 'new_value')
# 10000000 loops, best of 5: 90.7 ns per loop

%timeit if 'key' not in my_dict: my_dict['key'] = 'new_value'
# 10000000 loops, best of 5: 51 ns per loop

Check with dis

>>> import dis

>>> my_dict = {}
>>> dis.dis("my_dict.setdefault('key', 'new_value')")

  1           0 LOAD_NAME                0 (my_dict)
              2 LOAD_METHOD              1 (setdefault)
              4 LOAD_CONST               0 ('key')
              6 LOAD_CONST               1 ('new_value')
              8 CALL_METHOD              2
             10 RETURN_VALUE

>>> dis.dis("my_dict['key'] = my_dict.get('key', 'new_value')")

  1           0 LOAD_NAME                0 (my_dict)
              2 LOAD_METHOD              1 (get)
              4 LOAD_CONST               0 ('key')
              6 LOAD_CONST               1 ('new_value')
              8 CALL_METHOD              2
             10 LOAD_NAME                0 (my_dict)
             12 LOAD_CONST               0 ('key')
             14 STORE_SUBSCR
             16 LOAD_CONST               2 (None)
             18 RETURN_VALUE

>>> dis.dis("if 'key' not in my_dict: my_dict['key'] = 'new_value'")

1             0 LOAD_CONST               0 ('key')
              2 LOAD_NAME                0 (my_dict)
              4 COMPARE_OP               7 (not in)
              6 POP_JUMP_IF_FALSE       16
              8 LOAD_CONST               1 ('new_value')
             10 LOAD_NAME                0 (my_dict)
             12 LOAD_CONST               0 ('key')
             14 STORE_SUBSCR
        >>   16 LOAD_CONST               2 (None)
             18 RETURN_VALUE
  • Related