2015-04-14 15 views
6

Đây thực sự là một biến thể của câu hỏi này, nhưng không phải là một trùng lặp:Python ngược/inverse một ánh xạ (nhưng với nhiều giá trị cho mỗi phím)

Python reverse/invert a mapping

Với một cuốn từ điển như vậy:

mydict= { 'a': ['b', 'c'], 'd': ['e', 'f'] }

Làm thế nào người ta có thể đảo ngược dict này để có được:

inv_mydict = { 'b':'a', 'c':'a', 'e':'d', 'f':'d' }

Lưu ý rằng giá trị span duy nhất theo từng khóa.

Note: trước đây tôi đã có cú pháp map = ...dict = ... Nhắc nhở không sử dụng mapdict khi chúng được tích hợp chức năng, xem ý kiến ​​tuyệt vời và câu trả lời dưới đây :)

+1

'map' là từ khóa, không sử dụng làm tên từ điển. –

+0

Tôi đã thay đổi từ ngữ thành dict là kết quả là –

+2

@KevinLee, 'dict' cũng là một từ khóa :-)) – ForceBru

Trả lời

10

TL; DR

Sử dụng hiểu từ điển, như thế này

>>> my_map = { 'a': ['b', 'c'], 'd': ['e', 'f'] } 
>>> {value: key for key in my_map for value in my_map[key]} 
{'c': 'a', 'f': 'd', 'b': 'a', 'e': 'd'} 

Các hiểu từ điển thấy ở trên có chức năng tương đương với cấu trúc vòng lặp sau đó populates một từ điển rỗng

>>> inv_map = {} 
>>> for key in my_map: 
...  for value in my_map[key]: 
...   inv_map[value] = key 
... 
>>> inv_map 
{'c': 'a', 'f': 'd', 'b': 'a', 'e': 'd'} 

Lưu ý: Sử dụngmap bóng được xây dựng trong map chức năng. Vì vậy, không sử dụng nó như một tên biến trừ khi bạn biết những gì bạn đang làm.


cách tương tự khác cũng làm như vậy

Python 3.x

Bạn có thể sử dụng dict.items, như thế này

>>> {value: key for key, values in my_map.items() for value in values} 
{'c': 'a', 'f': 'd', 'b': 'a', 'e': 'd'} 

Chúng tôi sử dụng phương pháp items() đây, mà sẽ tạo ra một đối tượng xem từ từ điển wh ich sẽ cung cấp cho các cặp khóa giá trị khi lặp lại. Vì vậy, chúng tôi chỉ lặp lại nó và xây dựng một từ điển mới với ánh xạ ngược.

Python 2.x

Bạn có thể sử dụng dict.iteritems như thế này

>>> {value: key for key, values in my_map.iteritems() for value in values} 
{'c': 'a', 'b': 'a', 'e': 'd', 'f': 'd'} 

Chúng tôi không thích items() phương pháp trong 2.x, bởi vì nó sẽ trả về một danh sách các cặp khóa-giá trị . Chúng tôi không muốn xây dựng một danh sách chỉ để lặp lại và xây dựng một từ điển mới. Đó là lý do tại sao chúng tôi thích iteritems(), trả về một đối tượng trình lặp cung cấp một cặp giá trị quan trọng khi lặp lại.

Lưu ý: Tương đương thực tế của Python 3.x items sẽ là phương thức Python 2.x viewitems, trả về đối tượng xem. Đọc thêm về đối tượng xem trong tài liệu chính thức, here.


iter* vs view* phương pháp trong Python 2.x

Sự khác biệt chính giữa iter* chức năng và chức năng view* bằng Python 2.x là, các đối tượng xem phản ánh tình trạng hiện tại của từ điển. Ví dụ,

>>> d = {1: 2} 
>>> iter_items = d.iteritems() 
>>> view_items = d.viewitems() 

bây giờ chúng ta thêm một yếu tố mới vào từ điển

>>> d[2] = 3 

Nếu bạn cố gắng để kiểm tra xem (2, 3) (cặp key-value) là trong iter_items, nó sẽ ném ra một lỗi

>>> (2, 3) in iter_items 
Traceback (most recent call last): 
    File "<input>", line 1, in <module> 
RuntimeError: dictionary changed size during iteration 

nhưng đối tượng xem sẽ phản ánh trạng thái hiện tại của từ điển. Vì vậy, nó sẽ hoạt động tốt

>>> (2, 3) in view_items 
True 
2
mp = { 'a': ['b', 'c'], 'd': ['e', 'f'] } 

pm={} 
for x in mp.iterkeys(): 
    for d in mp[x]: 
     pm[d]=x 

print pm 

Output:

{ 'c': 'a', 'b': 'a', 'e': 'd', ' f ': 'd'}

Lưu ý: một cuốn từ điển là một cấu trúc dữ liệu unordored, vì vậy kết quả có thể không được đặt hàng như bạn muốn nó được.

+0

Cảm ơn lời nhắc không theo thứ tự, tôi đã sử dụng thư viện 'natsort' để sắp xếp từ điển của mình. –

Các vấn đề liên quan