更新词典列表中的列表值

时间:2022-04-08 04:26:42

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}]