I have a list of dictionaries (much like in JSON). I want to apply a function to a key in every dictionary of the list.
我有一个字典列表(很像JSON)。我想将一个函数应用于列表的每个字典中的一个键。
>> d = [{'a': 2, 'b': 2}, {'a': 1, 'b': 2}, {'a': 1, 'b': 2}, {'a': 1, 'b': 2}]
# Desired value
[{'a': 200, 'b': 2}, {'a': 100, 'b': 2}, {'a': 100, 'b': 2}, {'a': 100, 'b': 2}]
# If I do this, I can only get the changed key
>> map(lambda x: {k: v * 100 for k, v in x.iteritems() if k == 'a'}, d)
[{'a': 200}, {'a': 100}, {'a': 100}, {'a': 100}]
# I try to add the non-modified key-values but get an error
>> map(lambda x: {k: v * 100 for k, v in x.iteritems() if k == 'a' else k:v}, d)
SyntaxError: invalid syntax
File "<stdin>", line 1
map(lambda x: {k: v * 100 for k, v in x.iteritems() if k == 'a' else k:v}, d)
How can I achieve this?
我怎样才能做到这一点?
EDIT: 'a' and 'b' are not the only keys. These were selected for demo purposes only.
编辑:'a'和'b'不是唯一的关键。这些仅用于演示目的。
5 个解决方案
#1
7
Iterate through the list and update the desired dict item,
遍历列表并更新所需的dict项,
lst = [{'a': 2, 'b': 2}, {'a': 1, 'b': 2}, {'a': 1, 'b': 2}, {'a': 1, 'b': 2}]
for d in lst:
d['a'] *= 100
Using list comprehension will give you speed but it will create a new list and new n dict, It's useful if you don't wanna mutate your list, here it is
使用列表理解会给你速度,但它会创建一个新的列表和新的字典,如果你不想改变你的列表,这是有用的,这里是
new_lst = [{**d, 'a': d['a']*100} for d in lst]
In python 2.X we can't use {**d}
so I built custom_update
based on the update
and the code will be
在python 2.X中我们不能使用{** d}所以我根据更新构建了custom_update,代码将是
def custom_update(d):
new_dict = dict(d)
new_dict.update({'a':d['a']*100})
return new_dict
[custom_update(d) for d in lst]
If for every item in the list you want to update a different key
如果列表中的每个项目都要更新其他键
keys = ['a', 'b', 'a', 'b'] # keys[0] correspond to lst[0] and keys[0] correspond to lst[0], ...
for index, d in enumerate(lst):
key = keys[index]
d[key] *= 100
using list comprehension
使用列表理解
[{**d, keys[index]: d[keys[index]] * 100} for index, d in enumerate(lst)]
In python 2.x the list comprehension will be
在python 2.x中,列表理解将是
def custom_update(d, key):
new_dict = dict(d)
new_dict.update({key: d[key]*100})
return new_dict
[custom_update(d, keys[index]) for index, d in enumerate(lst)]
#2
5
You can use your inline conditionals (ternaries) in a better location within a comprehension:
您可以在理解中的更好位置使用内联条件(三元组):
>>> d = [{'a': 2, 'b': 2}, {'a': 1, 'b': 2}, {'a': 1, 'b': 2}, {'a': 1, 'b': 2}]
>>> d2 = [{k: v * 100 if k == 'a' else v for k, v in i.items()} for i in d]
>>> d2
[{'a': 200, 'b': 2}, {'a': 100, 'b': 2}, {'a': 100, 'b': 2}, {'a': 100, 'b': 2}]
#3
1
Your map()
call is close to working, you just need to change the order of your dict comprehension, and turn else k:v
into else v
:
你的map()调用接近于工作,你只需要改变你的dict理解的顺序,然后将k:v转换为else v:
>>> d = [{'a': 2, 'b': 2}, {'a': 1, 'b': 2}, {'a': 1, 'b': 2}, {'a': 1, 'b': 2}]
>>> list(map(lambda x: {k: v * 100 if k == 'a' else v for k, v in x.items()}, d))
[{'a': 200, 'b': 2}, {'a': 100, 'b': 2}, {'a': 100, 'b': 2}, {'a': 100, 'b': 2}]
#4
0
If you are using a function, you may want to provide a target key and corresponding value:
如果您使用的是函数,则可能需要提供目标键和相应的值:
d = [{'a': 2, 'b': 2}, {'a': 1, 'b': 2}, {'a': 1, 'b': 2}, {'a': 1, 'b': 2}]
f = lambda new_val, d1, key='a': {a:b*new_val if a == key else b for a, b in d1.items()}
new_d = list(map(lambda x:f(100, x), d))
Output:
输出:
[{'a': 200, 'b': 2}, {'a': 100, 'b': 2}, {'a': 100, 'b': 2}, {'a': 100, 'b': 2}]
#5
0
After your edit of "'a'
and 'b'
are not the only keys. These were selected for demo purposes only", here is a very simple map
function that alters only the value of 'a'
, and leaves the rest as is:
在编辑“'a'和'b'不是唯一的键之后。这些只是为了演示目的而被选中”,这是一个非常简单的map函数,只改变'a'的值,其余部分保留原样:
map(lambda x: x.update({'a': x['a']*100}), d)
My original answer was:
我原来的答案是:
I think the simplest and most appropriate way of this is iterating in d
and utilizing the fact that each item in d
is a dictionary that has keys 'a'
and 'b'
:
我认为最简单和最合适的方法是迭代d并利用d中的每个项目都是具有键'a'和'b'的字典:
res = [{'a':e['a']*100, 'b':e['b']} for e in d]
Result:
结果:
[{'a': 200, 'b': 2}, {'a': 100, 'b': 2}, {'a': 100, 'b': 2}, {'a': 100, 'b': 2}]
#1
7
Iterate through the list and update the desired dict item,
遍历列表并更新所需的dict项,
lst = [{'a': 2, 'b': 2}, {'a': 1, 'b': 2}, {'a': 1, 'b': 2}, {'a': 1, 'b': 2}]
for d in lst:
d['a'] *= 100
Using list comprehension will give you speed but it will create a new list and new n dict, It's useful if you don't wanna mutate your list, here it is
使用列表理解会给你速度,但它会创建一个新的列表和新的字典,如果你不想改变你的列表,这是有用的,这里是
new_lst = [{**d, 'a': d['a']*100} for d in lst]
In python 2.X we can't use {**d}
so I built custom_update
based on the update
and the code will be
在python 2.X中我们不能使用{** d}所以我根据更新构建了custom_update,代码将是
def custom_update(d):
new_dict = dict(d)
new_dict.update({'a':d['a']*100})
return new_dict
[custom_update(d) for d in lst]
If for every item in the list you want to update a different key
如果列表中的每个项目都要更新其他键
keys = ['a', 'b', 'a', 'b'] # keys[0] correspond to lst[0] and keys[0] correspond to lst[0], ...
for index, d in enumerate(lst):
key = keys[index]
d[key] *= 100
using list comprehension
使用列表理解
[{**d, keys[index]: d[keys[index]] * 100} for index, d in enumerate(lst)]
In python 2.x the list comprehension will be
在python 2.x中,列表理解将是
def custom_update(d, key):
new_dict = dict(d)
new_dict.update({key: d[key]*100})
return new_dict
[custom_update(d, keys[index]) for index, d in enumerate(lst)]
#2
5
You can use your inline conditionals (ternaries) in a better location within a comprehension:
您可以在理解中的更好位置使用内联条件(三元组):
>>> d = [{'a': 2, 'b': 2}, {'a': 1, 'b': 2}, {'a': 1, 'b': 2}, {'a': 1, 'b': 2}]
>>> d2 = [{k: v * 100 if k == 'a' else v for k, v in i.items()} for i in d]
>>> d2
[{'a': 200, 'b': 2}, {'a': 100, 'b': 2}, {'a': 100, 'b': 2}, {'a': 100, 'b': 2}]
#3
1
Your map()
call is close to working, you just need to change the order of your dict comprehension, and turn else k:v
into else v
:
你的map()调用接近于工作,你只需要改变你的dict理解的顺序,然后将k:v转换为else v:
>>> d = [{'a': 2, 'b': 2}, {'a': 1, 'b': 2}, {'a': 1, 'b': 2}, {'a': 1, 'b': 2}]
>>> list(map(lambda x: {k: v * 100 if k == 'a' else v for k, v in x.items()}, d))
[{'a': 200, 'b': 2}, {'a': 100, 'b': 2}, {'a': 100, 'b': 2}, {'a': 100, 'b': 2}]
#4
0
If you are using a function, you may want to provide a target key and corresponding value:
如果您使用的是函数,则可能需要提供目标键和相应的值:
d = [{'a': 2, 'b': 2}, {'a': 1, 'b': 2}, {'a': 1, 'b': 2}, {'a': 1, 'b': 2}]
f = lambda new_val, d1, key='a': {a:b*new_val if a == key else b for a, b in d1.items()}
new_d = list(map(lambda x:f(100, x), d))
Output:
输出:
[{'a': 200, 'b': 2}, {'a': 100, 'b': 2}, {'a': 100, 'b': 2}, {'a': 100, 'b': 2}]
#5
0
After your edit of "'a'
and 'b'
are not the only keys. These were selected for demo purposes only", here is a very simple map
function that alters only the value of 'a'
, and leaves the rest as is:
在编辑“'a'和'b'不是唯一的键之后。这些只是为了演示目的而被选中”,这是一个非常简单的map函数,只改变'a'的值,其余部分保留原样:
map(lambda x: x.update({'a': x['a']*100}), d)
My original answer was:
我原来的答案是:
I think the simplest and most appropriate way of this is iterating in d
and utilizing the fact that each item in d
is a dictionary that has keys 'a'
and 'b'
:
我认为最简单和最合适的方法是迭代d并利用d中的每个项目都是具有键'a'和'b'的字典:
res = [{'a':e['a']*100, 'b':e['b']} for e in d]
Result:
结果:
[{'a': 200, 'b': 2}, {'a': 100, 'b': 2}, {'a': 100, 'b': 2}, {'a': 100, 'b': 2}]