简体   繁体   English

“扁平化”字典列表

[英]“Flattening” a list of dictionaries

So my aim is to go from:所以我的目标是从:

fruitColourMapping = [{'apple': 'red'}, {'banana': 'yellow'}]

to

finalMap = {'apple': 'red', 'banana': 'yellow'}

A way I got is:我得到的一个方法是:

 from itertools import chain
 fruits = list(chain.from_iterable([d.keys() for d in fruitColourMapping]))
 colour = list(chain.from_iterable([d.values() for d in fruitColourMapping]))
 return dict(zip(fruits, colour))

Is there any better more pythonic way?有没有更好的pythonic方式?

Why copy at all?为什么要复制?

In Python 3, you can use the new ChainMap :在 Python 3 中,您可以使用新的ChainMap

A ChainMap groups multiple dicts (or other mappings) together to create a single, updateable view. ChainMap 将多个字典(或其他映射)组合在一起以创建单个可更新视图。
The underlying mappings are stored in a list.底层映射存储在一个列表中。 That list is public and can accessed or updated using the maps attribute.该列表是公开的,可以使用maps属性访问或更新。 There is no other state.没有其他状态。 Lookups search the underlying mappings successively until a key is found.查找会连续搜索底层映射,直到找到一个键。 In contrast, writes, updates, and deletions only operate on the first mapping.相比之下,写入、更新和删除仅对第一个映射进行操作。

All you need is this ( do change the names to abide by Python naming conventions ):所有你需要的是这样的(更改名称共同遵守Python的命名约定):

from collections import ChainMap
fruit_colour_mapping = [{'apple': 'red'}, {'banana': 'yellow'}]
final_map = ChainMap(*fruit_colour_mapping)

And then you can use all the normal mapping operations:然后你可以使用所有正常的映射操作:

# print key value pairs:
for element in final_map.items():
    print(element)

# change a value:
final_map['banana'] = 'green'    # supermarkets these days....

# access by key:
print(final_map['banana'])
finalMap = {}
for d in fruitColourMapping:
    finalMap.update(d)
{k: v for d in fruitColourMapping for k, v in d.items()}

Rather than deconstructing and reconstructing, just copy and update:而不是解构和重建,只需复制和更新:

final_map = {}
for fruit_color_definition in fruit_color_mapping:
    final_map.update(fruit_color_definition)
dict(d.items()[0] for d in fruitColourMapping)

Approach方法

Use reduce to apply each dict to an empty initializer.使用reduce将每个 dict 应用到一个空的初始值设定项。 Since dict.update always returns None , use d.update(src) or d to give reduce the desired return value.由于dict.update总是返回None ,使用d.update(src) or dreduce所需的返回值。

Code代码

final_dict = reduce(lambda d, src: d.update(src) or d, dicts, {})

Test测试

>>> dicts = [{'a': 1, 'b': 2}, {'b': 3, 'c': 4}, {'a': 6}]
>>> final_dict = reduce(lambda d, src: d.update(src) or d, dicts, {})
>>> final_dict
{'a': 6, 'c': 4, 'b': 3}

Given给定的

d1, d2 = [{'apple': 'red'}, {'banana': 'yellow'}]

Code代码

In Python 3.5, dictionary unpacking was introduced (see PEP 448 ):在 Python 3.5 中,引入了字典解包(参见PEP 448 ):

{**d1, **d2}
# {'apple': 'red', 'banana': 'yellow'}

In Python 3.9, the merge operator was introduced:在 Python 3.9 中,引入了合并运算符

d1 | d2
# {'apple': 'red', 'banana': 'yellow'}

I came up with a interesting one liner.我想出了一个有趣的单衬。

>>> a = [{"wow": 1}, {"ok": 2}, {"yeah": 3}, {"ok": [1,2,3], "yeah": True}]
>>> a = dict(sum(map(list, map(dict.items, a)), []))
>>> a
{'wow': 1, 'ok': [1, 2, 3], 'yeah': True}

你也可以试试:

finalMap = dict(item for mapping in fruitColourMapping for item in mapping.items())

Why not unpacking, python 3.5 up: 为什么不拆包,python 3.5 up:

a, b = [{'apple': 'red'}, {'banana': 'yellow'}]
print(dict(a,**b))

Now you've got: 现在你有了:

{'apple': 'red', 'banana': 'yellow'}

For the output. 对于输出。

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

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