2010-11-20 50 views
6

Tôi có nhiều từ điển với các phím khác nhau và thông thường, cộng với các phím khác nhau và thông thường trong từ điển lồng nhau. Dưới đây là một ví dụ đơn giản, các từ điển thực tế có hàng ngàn khóa.Hợp nhất các từ điển lồng nhau, bằng các phím lồng nhau?

{1:{"Title":"Chrome","Author":"Google","URL":"http://"}} 
{1:{"Title":"Chrome","Author":"Google","Version":"7.0.577.0"}} 
{2:{"Title":"Python","Version":"2.5"}} 

Tôi muốn nhập vào một từ điển duy nhất.

{1:{"Title":"Chrome","Author":"Google","URL":"http://","Version":"7.0.577.0"}, 
2:{"Title":"Python","Version":"2.5"}} 

tôi có thể lặp qua hai cuốn từ điển, so sánh phím và update các từ điển lồng nhau, nhưng có lẽ là một hiệu quả hơn, hoặc pythonic, cách để làm điều này. Nếu không, đó là hiệu quả nhất?

Không được so sánh giá trị của từ điển lồng nhau.

+0

Nếu bạn đang thực sự lập bản đồ các phím số nguyên tuần tự, nó sẽ không có ý nghĩa hơn đối với sản xuất một danh sách như đầu ra? –

+0

Rất nhiều cuộc thảo luận và lời khuyên ở đây là tốt: http://stackoverflow.com/questions/38987/how-can-i-merge-two-python-dictionaries-as-a-single-expression – mjhm

+0

Có vẻ rất không thực tế rằng mỗi "vài từ điển" có chính xác một cặp khóa/giá trị trong đó - làm cho người ta tự hỏi tại sao chúng là từ điển khi một tuple hoặc danh sách đơn giản với hai mục trong nó cũng hoạt động tốt. – martineau

Trả lời

5
from collections import defaultdict 

mydicts = [ 
    {1:{"Title":"Chrome","Author":"Google","URL":"http://"}}, 
    {1:{"Title":"Chrome","Author":"Google","Version":"7.0.577.0"}}, 
    {2:{"Title":"Python","Version":"2.5"}}, 
] 

result = defaultdict(dict) 

for d in mydicts: 
    for k, v in d.iteritems(): 
     result[k].update(v) 

print result 

defaultdict(<type 'dict'>, 
    {1: {'Version': '7.0.577.0', 'Title': 'Chrome', 
     'URL': 'http://', 'Author': 'Google'}, 
    2: {'Version': '2.5', 'Title': 'Python'}}) 
+0

Tinh chỉnh nhỏ: 'for' thứ hai có thể được thay thế bằng' k, v = next (d.iteritems()) 'và dòng tiếp theo được trích dẫn. Không thực sự nhiều sự khác biệt, nhưng nó sẽ * nhìn * nhanh hơn. ;-) – martineau

+0

@martineau: nó cũng sẽ ít hữu ích hơn: 'next()' chỉ hoạt động trên python 2.6+. Ngoài ra cách tôi đã viết chấp nhận nhiều hơn một khóa trên mỗi 'dict', hoặc trống' dict' mà không bị nghẹt thở hoặc làm sai điều gì đó – nosklo

+0

Vâng, bạn chính xác về 'next()' không có sẵn trước phiên bản v2.6 - - khi viết nó tôi quên OP muốn có một giải pháp tương thích v2.5. Tuy nhiên, có thể cho rằng việc chấp nhận 'dict' lồng nhau không đúng với nhiều hơn một khóa sẽ là điều mong muốn, và cuối cùng, 'next()' có thể xử lý rỗng 'dict' s mà không có vấn đề gì. Tất cả những điều được xem xét, tôi vẫn tin rằng bình luận của tôi là một quan sát hợp lệ cho những người ở đó bằng cách sử dụng ít nhất là v2.6 của Python. – martineau

2

Từ ví dụ của bạn, có vẻ như bạn có thể làm điều gì đó như:

from collections import defaultdict 
mydict = defaultdict(dict) 
for indict in listofdicts: 
    k, v = indict.popitem() 
    mydict[k].update(v) 
Các vấn đề liên quan