简体   繁体   English

在列表中设置字典字段的pythonic方法是什么

[英]What is the pythonic way of setting fields of a dict in a list

I have two lists, one containing int values:我有两个列表,一个包含 int 值:

values = [5,10,15,20]

the other is a list of dicts:另一个是字典列表:

dicts = [{'a':0, 'b':0, 'c':0},
         {'a':0, 'b':0, 'c':0},
         {'a':0, 'b':0, 'c':0},
         {'a':0, 'b': 0, 'c':0}]

I want to get the first value from values list and set the field "a" of the first dict with the value coming from the "values" list and so on.我想从值列表中获取第一个值,并使用来自“值”列表的值设置第一个 dict 的字段“a”,依此类推。 In other words output should be:换句话说,输出应该是:

dicts = [{'a':5, 'b':0, 'c':0},
         {'a':10, 'b':0, 'c':0},
         {'a':15, 'b':0, 'c':0},
         {'a':20, 'b': 0, 'c':0}]

What is the Pythonic way to do this?这样做的 Pythonic 方法是什么?

Well you could use a zip to set the value for 'a' for every dictionary.好吧,您可以使用zip为每个字典设置'a'的值。 Something like:就像是:

for dic,val in zip(dicts,values):
    dic['a'] = val

Or putting it in a one-liner :或者把它放在一个单线中

for dic,val in zip(dicts,values): dic['a'] = val

Note that there is no difference with the previous code fragment.请注意,与之前的代码片段没有区别 It depends on what your eye likes the most.这取决于你的眼睛最喜欢什么。

We here update the dictionaries: we do no create copies, etc. That is an important distinction since variables that could reference to the given dictionaries will reflect the changes we make.我们在这里更新字典:我们不创建副本等。这是一个重要的区别,因为可以引用给定字典的变量将反映我们所做的更改。

zip(..) takes as input a sequence or more iterables (here dicts and values ) and generates tuples of elements of these iterables. zip(..)将一个序列或多个可迭代对象(这里是dictsvalues )作为输入,并生成这些可迭代对象的元素的元组。 So it emits:所以它发出:

(values[0],dicts[0]), (values[1],dicts[1]), ...

Now we do tuple-unpacking : we unify val and dic with one of the values and one of the dicts .现在我们进行元组解包:我们将valdic与其中一个values和一个dicts统一起来。 For each of the tuples we thus set the dic['a'] value.因此,对于每个元组,我们设置dic['a']值。

Console test:控制台测试:

$ python3
Python 3.5.2 (default, Nov 17 2016, 17:05:23) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> values = [5,10,15,20]
>>> dicts = [{'a':0, 'b':0, 'c':0},
...          {'a':0, 'b':0, 'c':0},
...          {'a':0, 'b':0, 'c':0},
...          {'a':0, 'b': 0, 'c':0}]
>>> for dic,val in zip(dicts,values): dic['a'] = val
... 
>>> dicts
[{'b': 0, 'c': 0, 'a': 5}, {'b': 0, 'c': 0, 'a': 10}, {'b': 0, 'c': 0, 'a': 15}, {'b': 0, 'c': 0, 'a': 20}]

For the sake of a Pythonic one-liner (although I strongly suggest you prefer Willem's answer for clarity/readability ):为了 Pythonic 的单行代码(尽管我强烈建议您更喜欢 Willem 的答案以确保清晰/可读性):

dicts = [{key: val if key != 'a' else z_val 
            for key, val in d.items()} for d, z_val in zip(dicts, values)]

dicts
Out[5]: 
[{'a': 5, 'b': 0, 'c': 0},
 {'a': 10, 'b': 0, 'c': 0},
 {'a': 15, 'b': 0, 'c': 0},
 {'a': 20, 'b': 0, 'c': 0}]

Edit: Removed the redundant if else for the dictionary keys.编辑:删除了字典键的多余if else

Try this code :试试这个代码:

values = [5,10,15,20]
dicts = [{'a':0, 'b':0, 'c':0},
         {'a':0, 'b':0, 'c':0},
         {'a':0, 'b':0, 'c':0},
         {'a':0, 'b': 0, 'c':0}]

res1 =  dict(zip(dicts[0],zip(*[d.values() for d in dicts])))# tronspose a list of dicts /// res1 = {'a': (0, 0, 0, 0), 'c': (0, 0, 0, 0), 'b': (0, 0, 0, 0)}
res1['a'] = values
res = [dict(zip(res1,t)) for t in zip(*res1.values())]# tronspose res1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM