Edit the values in a list of dictionaries?
my_dicts = [
{ 'key1' : 'value1',
'key2' : 'value2' },
{ 'key1' : 'value1',
'key2' : 'value2' },
{ 'key1' : 'value1',
'key2' : 'value2' }]
What would be the most efficient way to replace all instances of 'value2' with 'value3' ?
Solution 1:
I did not do any timings, but you probably can't get much better than
for d in my_dicts:
d.update((k, "value3") for k, v in d.iteritems() if v == "value2")
Update for Python3
for d in my_dicts:
d.update((k, "value3") for k, v in d.items() if v == "value2")
Solution 2:
for x in my_dicts:
for y in x:
if x.get(y) == 'value2':
x.update({y: "value3"})
Solution 3:
Here's a very general answer designed to handle multiple occurrences of multiple values in large dictionaries. Handling simpler more specific cases and/or with small dictionaries -- like your example -- could be done significantly faster.
from collections import defaultdict
my_dicts = [
{ 'key1' : 'value1',
'key2' : 'value2' },
{ 'key1' : 'value1',
'key2' : 'value2',
'key3' : 'value2' }, # dup added for testing
{ 'key1' : 'value1',
'key2' : 'value2' }]
def reverse(dct):
""" Create dictionary mapping each value to list of one or more keys """
ret = defaultdict(list)
for key,val in dct.iteritems():
ret[val].append(key)
return ret
def replace_values(dicts, replacments):
""" Replace values in each dict in dicts """
for dct in dicts:
revdict = reverse(dct)
for oldval,newval in replacments.iteritems():
for key in revdict.get(oldval, []):
dct[key] = newval
replace_values(my_dicts, {'value2':'value3'})
print my_dicts
# [{'key2': 'value3', 'key1': 'value1'},
# {'key3': 'value3', 'key2': 'value3', 'key1': 'value1'},
# {'key2': 'value3', 'key1': 'value1'}]
Solution 4:
Python3.7 dict comprehension (will return a deep copy though):
update = {'key2':'value3'}
new_dicts = [{**d,**update} for d in my_dicts]