Làm cách nào để hợp nhất danh sách các phái thành một mệnh đề duy nhất?


124

Làm thế nào tôi có thể lật một danh sách các phái như thế này

[{'a':1}, {'b':2}, {'c':1}, {'d':2}]

Thành một mệnh đề duy nhất như thế này

{'a':1, 'b':2, 'c':1, 'd':2}


Đúng, mặc dù điều đó hợp nhất thành một danh sách chính tả.
Katriel

1
nó là một danh sách chứ không phải là dict: >>> type ([{'a': 1}, {'b': 2}]) <type 'list'>
killown 16/08/10

Thực sự nên có một lớp lót cho điều này xem xét tần suất nó xuất hiện. Có lý do gì khiến {** d for d in d_list} không được hỗ trợ không?
markemus

Câu trả lời:


163

Điều này phù hợp với các từ điển có độ dài bất kỳ:

>>> result = {}
>>> for d in L:
...    result.update(d)
... 
>>> result
{'a':1,'c':1,'b':2,'d':2}

Như một sự hiểu biết :

# Python >= 2.7
{k: v for d in L for k, v in d.items()}

# Python < 2.7
dict(pair for d in L for pair in d.items())


6
>>> L=[{'a': 1}, {'b': 2}, {'c': 1}, {'d': 2}]    
>>> dict(i.items()[0] for i in L)
{'a': 1, 'c': 1, 'b': 2, 'd': 2}

Lưu ý: thứ tự của 'b' và 'c' không khớp với kết quả đầu ra của bạn vì các số không có thứ tự

nếu các phần có thể có nhiều hơn một khóa / giá trị

>>> dict(j for i in L for j in i.items())

Không thành công nếu bất kỳ phái nào trong danh sách có nhiều hơn một mục.
PaulMcG

2
ho * (giả sử mỗi từ điển chỉ chứa một giá trị khóa cặp) * ho
Katriel

Ah, cũng lần đầu tiên tôi đăng một phương pháp làm việc với dicts chung, nhưng nó trông giống như OP không cần điều đó
John La Rooy

5

Đối với từ điển phẳng, bạn có thể làm điều này:

from functools import reduce
reduce(lambda a, b: dict(a, **b), list_of_dicts)

4

Điều này tương tự như @delnan nhưng cung cấp tùy chọn để sửa đổi các mục k / v (khóa / giá trị) và tôi tin rằng dễ đọc hơn:

new_dict = {k:v for list_item in list_of_dicts for (k,v) in list_item.items()}

ví dụ: thay thế k / v elems như sau:

new_dict = {str(k).replace(" ","_"):v for list_item in list_of_dicts for (k,v) in list_item.items()}

giải nén bộ tuple k, v từ trình tạo .items () từ điển sau khi kéo đối tượng dict ra khỏi danh sách


2
dict1.update( dict2 )

Điều này là không đối xứng vì bạn cần phải chọn làm gì với các khóa trùng lặp; trong trường hợp này, dict2sẽ ghi đè dict1. Đổi chúng theo cách khác.

CHỈNH SỬA: À, xin lỗi, không thấy.

Có thể thực hiện điều này trong một biểu thức duy nhất:

>>> from itertools import chain
>>> dict( chain( *map( dict.items, theDicts ) ) )
{'a': 1, 'c': 1, 'b': 2, 'd': 2}

Không có tín dụng cho tôi cho điều này cuối cùng!

Tuy nhiên, tôi cho rằng có thể có nhiều Pythonic hơn (rõ ràng> ngầm định, phẳng> lồng nhau) để làm điều này với một forvòng lặp đơn giản . YMMV.


1
nó là một danh sách chứ không phải là một dict: >>> type ([{'a': 1}, {'b': 2}]) <type 'list'>
killown

1

Bạn có thể sử dụng chức năng tham gia từ thư viện funcy :

from funcy import join
join(list_of_dicts)

1

Cải tiến nhỏ cho câu trả lời @dietbuddha với việc giải nén từ điển từ PEP 448 , đối với tôi, nó dễ đọc hơn theo cách này, đồng thời, nó cũng nhanh hơn :

from functools import reduce
result_dict = reduce(lambda a, b: {**a, **b}, list_of_dicts)

Nhưng hãy nhớ rằng điều này chỉ hoạt động với các phiên bản Python 3.5+.


0
>>> dictlist = [{'a':1},{'b':2},{'c':1},{'d':2, 'e':3}]
>>> dict(kv for d in dictlist for kv in d.iteritems())
{'a': 1, 'c': 1, 'b': 2, 'e': 3, 'd': 2}
>>>

Lưu ý rằng tôi đã thêm cặp khóa / giá trị thứ hai vào từ điển cuối cùng để cho thấy nó hoạt động với nhiều mục nhập. Ngoài ra, các khóa từ các phái sau trong danh sách sẽ ghi đè lên cùng một khóa từ một chính tả trước đó.


-1

dic1 = {'Maria': 12, 'Paco': 22, 'Jose': 23} dic2 = {'Patricia': 25, 'Marcos': 22 'Tomas': 36}

dic2 = dict (dic1.items () + dic2.items ())

và đây sẽ là kết quả:

dic2 {'Jose': 23, 'Marcos': 22, 'Patricia': 25, 'Tomas': 36, 'Paco': 22, 'Maria': 12}

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.