2012-05-21 46 views
5

Tôi đang cố gắng sử dụng map() trên đối tượng dict_values được trả về bởi hàm values() trên từ điển. Tuy nhiên, tôi dường như không thể để có thể map() hơn một dict_values:Bản đồ Python() giá trị từ điển

map(print, h.values()) 
Out[31]: <builtins.map at 0x1ce1290> 

Tôi chắc rằng có một cách dễ dàng để làm điều này. Những gì tôi đang thực sự cố gắng làm là tạo ra một set() của tất cả các phím Counter trong từ điển của Counters, làm một cái gì đó như thế này:

# counters is a dict with Counters as values 
whole_set = set() 
map(lambda x: whole_set.update(set(x)), counters.values()) 

Có cách nào tốt hơn để làm điều này trong Python?

+0

Cố gắng đưa ra ví dụ đầu vào/đầu ra - nó làm cho nó dễ dàng hơn nhiều để xem những gì bạn đang cố gắng để đạt được. –

+0

Tôi không biết nếu bạn quan tâm đến ví dụ đầu tiên, nhưng điều này là tương đương: 'print (* h.values ​​(), sep = '\ n')' thành một phiên bản không phát của bản đồ. – Darthfett

Trả lời

13

Trong Python 3, map trả về một trình lặp, không phải danh sách. Bạn vẫn phải lặp qua nó, hoặc bằng cách gọi list trên nó một cách rõ ràng, hoặc bằng cách đặt nó trong một vòng lặp for. Tuy nhiên, bạn không nên sử dụng map theo cách này. map thực sự là để thu thập các giá trị trả về thành một chuỗi lặp lại. Vì không phải print cũng không phải set.update trả về một giá trị, sử dụng map trong trường hợp này không phải là thành ngữ.

Mục tiêu của bạn là đặt tất cả các khóa trong tất cả các bộ đếm trong counters vào một bộ duy nhất. Một cách để làm điều đó là sử dụng một biểu phát lồng nhau:

s = set(key for counter in counters.values() for key in counter) 

Ngoài ra còn đáng yêu cú pháp dict hiểu, trong đó có sẵn trong Python 2.7 và cao hơn (nhờ Lattyware!) Và có thể tạo ra bộ cũng như từ điển:

s = {key for counter in counters.values() for key in counter} 

cả hai đều tương đương như sau:

s = set() 
for counter in counters.values(): 
    for key in counter: 
     s.add(key) 
+0

Tuyệt vời, đó chính xác là những gì tôi đang tìm kiếm. Cám ơn rất nhiều! –

+2

Lưu ý rằng tùy chọn hơi sạch hơn ở đây là chỉ cần sử dụng một thiết lập hiểu, chứ không phải là một biểu thức máy phát điện vào constructor thiết lập - '{chìa khóa để truy cập trong counters.values ​​() cho khóa trong truy cập}'. –

0

Bạn muốn tập-đoàn của tất cả các giá trị của counters? I.e.,

counters[1].union(counters[2]).union(...).union(counters[n]) 

? Đó chỉ là functools.reduce:

import functools 

s = functools.reduce(set.union, counters.values()) 


Nếu counters.values() là chưa đặt (ví dụ, nếu họ danh sách), sau đó bạn nên biến chúng thành bộ đầu tiên. Bạn có thể làm điều đó bằng cách sử dụng dict comprehension sử dụng iteritems, đó là một chút vụng về:

>>> counters = {1:[1,2,3], 2:[4], 3:[5,6]} 
>>> counters = {k:set(v) for (k,v) in counters.iteritems()} 
>>> print counters 
{1: set([1, 2, 3]), 2: set([4]), 3: set([5, 6])} 

hoặc tất nhiên bạn có thể làm điều đó inline, vì bạn không quan tâm đến counters.keys():

>>> counters = {1:[1,2,3], 2:[4], 3:[5,6]} 
>>> functools.reduce(set.union, [set(v) for v in counters.values()]) 
set([1, 2, 3, 4, 5, 6]) 
Các vấn đề liên quan