问题
Given a list of dictionaries:
the_list = [{k1:v1,k2:v2}, {k1:v3, k3:v4}, {k1:v5,k2:v6},{k3:v7}]
How can I update the value for k2
based on a condition based on the value of k1
?
I would come up with this solution but it doesn't feel Pythonic. Better solutions anyone?
for item in the_list:
if set([k1,k2]) <= item.keys():
#cond evaluates to True or False
if cond(item[k1]):
item.update({k2:newvalue})
Maybe this can be done better with a map or lambda expression?
回答1:
This is the simplest code I came up with to perform the same operation:
my_list = [{k1:v1,k2:v2}, {k1:v3, k3:v4}, {k1:v5,k2:v6},{k3:v7}]
for my_dict in my_list:
if all (k in my_dict for k in ("k1", "k2")):
if cond(my_dict[k1]):
my_dict[k2] = newvalue # possibly pre-determined
Depending on the way cond
evaluates the value of k1
and/or newvalue
is generated, the code might be further more "Pythonized".
回答2:
well in python dir(dict) shows us available methods for dictionary, and "somemethod" in dir(dict) shows us if somemethod is available in sed data type. SO if we factor it in our problem we can se that in :
py.2.7->
['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__', '__eq__',\
'__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__',\
'__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__',\
'__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__',\
'__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'has_key', 'items', 'iteritems',\
'iterkeys', 'itervalues','keys', 'pop', 'popitem', 'setdefault', 'update', 'values', \
'viewitems', 'viewkeys', 'viewvalues']
py.3.5 ->
['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__', '__eq__',\
'__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__',\
'__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__',\
'__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__',\
'__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'has_key', 'items', 'iteritems',\
'iterkeys', 'itervalues', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values',\
'viewitems', 'viewkeys', 'viewvalues']
Now we can see several things here, pop
,popitem
,has_key
,'get', and since dictionary in python is not ordered or sorted ( it prints it out as it goes ) we can also use update
.
So first we need to transverse trough list of dictionaries and condition trough items, depending on size of your dictionary map or dictionary comprehension could do the trick or just dict.items() which returns list of tuples. so
def duDict(dictionary,codnitionElement,keyInQuesiton):
el = dictionary.pop(keyInQuesiton) #similar as list.pop
if condition(dictionary.get(codnitionElement)):
el = something
dictionary.update({keyInQuesiton:el })
else:pass
return dictionary
then something along the lines
condDict = lambda dict: duDict(dict,predefinedCondition,forKey)
map( condDict , listOfDicts )
Hope this helps
来源:https://stackoverflow.com/questions/41464870/update-a-value-in-a-list-of-dictionaries-in-python-based-on-a-condition-based-on