2012-01-19 89 views
197

Tôi có hai từ điển hiện có và tôi muốn 'thêm từ điển' vào một từ điển khác. Bởi vì tôi có nghĩa là chìa khóa, giá trị của từ điển khác nên được thực hiện vào từ điển đầu tiên. Ví dụ:Nối từ điển vào từ điển?

orig = { 
    'A': 1, 
    'B': 2, 
    'C': 3, 
} 

extra = { 
    'D': 4, 
    'E': 5, 
} 

dest = # something here involving orig and extra 

print dest 
{ 
    'A': 1, 
    'B': 2, 
    'C': 3, 
    'D': 4, 
    'E': 5 
} 

Tôi nghĩ rằng tất cả điều này có thể đạt được thông qua một vòng lặp for (có thể?), Nhưng có một số phương pháp điển hoặc bất kỳ thành phần khác mà tiết kiệm công việc này cho tôi? Các bộ từ điển thực tế tôi đang sử dụng là thực sự lớn ...

+15

Một vài câu trả lời chỉ ra 'orig.update (bổ sung)' thực hiện công việc. Do lưu ý rằng nếu 'extra' và' orig' có các phím chồng chéo, giá trị cuối cùng sẽ được lấy từ 'extra'. Ví dụ: 'd1 = {1: 1, 2: 2}; d2 = {2: 'ha!', 3: 3}; d1.update (d2) 'sẽ dẫn đến' d1' chứa '{1: 1, 2: 'ha!', 3: 3}'. –

Trả lời

310

Bạn có thể làm

orig.update(extra) 

hoặc, nếu bạn không muốn orig phải được sửa đổi, tạo một bản sao đầu tiên:

dest = dict(orig) # or orig.copy() 
dest.update(extra) 

Lưu ý rằng nếu thêm và orig có phím chồng chéo , giá trị cuối cùng sẽ được lấy từ thêm. Ví dụ,

>>> d1 = {1: 1, 2: 2} 
>>> d2 = {2: 'ha!', 3: 3} 
>>> d1.update(d2) 
>>> d1 
{1: 1, 2: 'ha!', 3: 3} 
+2

Có dict.copy(), làm cho các bản sao nông như phương pháp sao chép của bạn. – sleeplessnerd

+0

Tôi đã nhìn thấy thành ngữ dict (** orig) trước đó. Lợi thế hơn dict (orig) là gì? – DSM

+2

Sử dụng 'dict (** orig)' sẽ tạo ra một dict tạm thời mới được sử dụng làm đối số từ khóa cho hàm tạo dict. Sau đó, hàm tạo sẽ sao chép các giá trị từ đối số này vào chính nó. Vì vậy, bạn tạo một từ điển bổ sung với 'dict (** orig)'. Điều này là lãng phí khi các từ điển là lớn, như trong câu hỏi ban đầu. –

12

dict.update() vẻ như nó sẽ làm những gì bạn muốn ...

>> orig.update(extra) 
>>> orig 
{'A': 1, 'C': 3, 'B': 2, 'E': 5, 'D': 4} 
>>> 

Có lẽ, tuy nhiên, bạn không muốn cập nhật từ điển ban đầu của bạn , nhưng làm việc trên một bản sao:

>>> dest = orig.copy() 
>>> dest.update(extra) 
>>> orig 
{'A': 1, 'C': 3, 'B': 2} 
>>> dest 
{'A': 1, 'C': 3, 'B': 2, 'E': 5, 'D': 4} 
5

có là .update() phương pháp :)

cập nhật ([khác]) Cập nhật từ điển với cặp khóa/giá trị từ khác, ghi đè các khóa hiện có. Không trả lại.

cập nhật() chấp nhận một đối tượng từ điển khác hoặc một cặp khóa/giá trị có thể lặp lại (như bộ hoặc các vòng lặp có chiều dài hai). Nếu đối số từ khóa được chỉ định, từ điển sau đó được cập nhật với các cặp khóa/giá trị đó: d.update (red = 1, blue = 2).

Thay đổi trong phiên bản 2.4: Cho phép đối số là một cặp lặp/khóa giá trị và các đối số từ khóa được phép.

20

Giả sử rằng bạn không muốn thay đổi orig, bạn có thể làm một bản sao và bản cập nhật như các câu trả lời khác, hoặc bạn có thể tạo ra một từ điển mới trong một bước bằng cách đi qua tất cả các mục từ hai cuốn từ điển vào constructor dict:

from itertools import chain 
dest = dict(chain(orig.items(), extra.items())) 

Hoặc không itertools:

dest = dict(list(orig.items()) + list(extra.items())) 

Lưu ý rằng bạn chỉ cần phải vượt qua là kết quả của items() vào list() trên Python 3, vào ngày 2.x dict.items() đã trả về danh sách để bạn có thể thực hiện dict(orig.items() + extra.items()).

Là một trường hợp sử dụng tổng quát hơn, nói rằng bạn có một danh sách lớn của dicts mà bạn muốn kết hợp thành một dict duy nhất, bạn có thể làm một cái gì đó như thế này:

from itertools import chain 
dest = dict(chain.from_iterable(map(dict.items, list_of_dicts))) 
+1

Thực ra tôi thích cái này vì bạn có thể 'cập nhật' một từ điển trong cùng biểu thức mà bạn muốn sử dụng nó làm tham số, như: 'SomeClass (** dict (args.items() + {'special': a_value,}.items())) ' – carlosayam

5

Câu trả lời tôi muốn cung cấp là "sử dụng collections.ChainMap", nhưng tôi chỉ phát hiện ra rằng nó chỉ được thêm vào trong Python 3.3: https://docs.python.org/3.3/library/collections.html#chainmap-objects

Bạn có thể thử nôi lớp từ 3.3 nguồn mặc dù: http://hg.python.org/cpython/file/3.3/Lib/collections/init.py#l763

đây là một ít tính năng đầy đủ Python 2.x compatib Phiên bản le (cùng một tác giả): http://code.activestate.com/recipes/305268-chained-map-lookups/

Thay vì mở rộng/ghi đè một từ điển với từ điển khác bằng dict.merge hoặc tạo một bản sao bổ sung kết hợp cả hai, bạn tạo một chuỗi tra cứu tìm kiếm theo thứ tự. Bởi vì nó không trùng lặp ánh xạ, nên nó sử dụng rất ít bộ nhớ, và thấy những sửa đổi sau này cho bất kỳ ánh xạ phụ nào. Vì vấn đề đặt hàng bạn cũng có thể sử dụng chuỗi để mặc định lớp (tức là người dùng prefs> config> env).

17

Cách pythonic nhất (và một chút nhanh hơn) để thực hiện điều này là bởi:

dest = {**orig, **extra} 

Hoặc, tùy thuộc vào vấn đề để giải quyết, có lẽ:

dest = {**orig, 'D': 4, 'E': 5} 
+2

thật đáng buồn nó không hoạt động cho 2.x (((chỉ dành cho 3.x – madjardi

+1

dict (itertools.chain (d.items(), y.items())) – madjardi

+0

Cả hai phiên bản chỉ cho tôi một lỗi cú pháp trong 3.x IDLE – Noumenon

0

Một ba-liner để kết hợp hoặc hợp nhất hai từ điển:

dest = {} 
dest.update(orig) 
dest.update(extra) 

Điều này tạo từ điển mới dest witho ut sửa đổi origextra.

Lưu ý: Nếu khóa có giá trị khác nhau trong origextra, thì extra ghi đè orig.

+0

Hoạt động ở cả Python 2 và Python 3. – jkdev