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