2012-05-02 19 views
8

Có cách nào để hiệu quả lặp qua các giá trị/mục trong từ điển hoạt động trong cả Python 2 và Python 3?Máy phát điện để lặp qua một từ điển thống nhất trong cả Python 2 và 3

Trong Python 2, tôi có thể viết

for x in mydict: 
for x in mydict.iterkeys(): 
for x in mydict.viewkeys(): 
for x in mydict.itervalues(): 
for x in mydict.viewvalues(): 
for x in mydict.iteritems(): 
for x in mydict.viewitems(): 

và bằng Python 3, tôi có các khả năng sau:

for x in mydict: 
for x in mydict.keys(): 
for x in mydict.values(): 
for x in mydict.items(): 

Vì vậy, tôi có thể lặp qua các phím với for x in mydict, và rằng công trình trong cả Python 2 và 3. Nhưng có cách nào để lặp qua các giá trị và các cặp khóa-giá trị ('items') hoạt động trên toàn cầu không? Tôi cần nó để viết mã Python có thể chạy trong cả hai phiên bản Python.

(Trên một mặt lưu ý, những trở ngại khác với vòng lặp có thể được bỏ qua một cách dễ dàng, lấy ví dụ:

if sys.version_info.major<3: 
    from itertools import izip as zip, imap as map 

Tuy nhiên, các phương pháp điển không thể được định nghĩa lại một cách dễ dàng như mapzip.)

Bất kỳ ý tưởng?

+1

EDIT: Tôi nghĩ bạn muốn nói máy phát điện lặp lại từ điển – jamylak

+0

@jamylak: vâng, cảm ơn. – Daniel

Trả lời

9

giá trị() phiên bản của Just another người đần độn của trả lời

for value in (mydict[key] for key in mydict): 

hoặc

def dict_values(d): 
    return (mydict[key] for key in mydict) 

def dict_items(d): 
    return ((key, mydict[key]) for key in mydict) 

for value in dict_values(mydict): 
    ... 

for value in dict_items(mydict): 
    ... 

Điều này là khá crappy mặc dù. Bạn có thể kiểm tra phiên bản python và thay vì trả lại các máy phát điện, trở về d.items() hoặc d.iteritems() phù hợp

Tôi nghĩ rằng một câu hỏi tốt hơn có thể làm thế nào để viết mã python2 rằng hoạt động tốt với 2to3 và tạo ra mã Python3 tốt

+4

+1 cho câu cuối cùng. – Daenyth

+0

Tôi ủng hộ đề xuất của gnibbler về việc kiểm tra phiên bản Python (một lần, ở đầu tập lệnh Python) và định nghĩa các hàm trả về trình lặp chính xác 'd.items()' hoặc 'd.iteritems()'. – Daniel

0

Python2.7 có phương thức .items trong từ điển cho phép bạn lặp lại (khóa, giá trị) tuple. Python3 có cùng một API (mặc dù việc thực hiện khác nhau). Điều này có phù hợp với bạn không?

+0

nhưng trong Python2, '.items()' xây dựng một danh sách tạm thời mà OP đang cố tránh –

+0

Câu hỏi không rõ ràng lắm nhưng tôi nghĩ rằng tác giả muốn tạo ra máy phát. Tôi đã thay đổi tiêu đề của câu hỏi để phản ánh điều đó. – jamylak

+0

Tôi không nhận thấy điều đó. Cảm ơn. –

3

này sẽ cung cấp cho bạn một máy phát điện:

for key,value in ((key,mydict[key] for key in mydict) 

Nếu bạn muốn có một danh sách, sử dụng [] xung quanh các biểu hiện thay cho() ở bên ngoài

+1

Một cách dễ dàng hơn là sử dụng mydict.iteritems() –

+0

Những gì bạn có trong bài đăng sẽ hoạt động ở cả 2 và 3 nhưng '.iteritems() 'không tồn tại trong 3. Ít nhất không phải bằng tên đó, nó được đổi tên thành' .items() '. –

+0

Bạn chỉ có thể sử dụng giải pháp ở trên. Tôi thích tránh xa các danh sách vì nếu kích thước từ điển quá lớn, tôi tin rằng việc tạo một danh sách mới sẽ tạo ra một danh sách lớn. –

7

Các mã sau đây hoạt động trong cả Py2 và Py3:

def iteritems(d): 
    'Factor-out Py2-to-3 differences in dictionary item iterator methods' 
    try: 
     return d.iteritems() 
    except AttributeError: 
     return d.items() 

d = dict(red=1, blue=2, green=3) 
for k, v in iteritems(d): 
    print(k) 
    print(v) 
    print('') 

Lưu ý, giải pháp này có lợi thế là sử dụng trình lặp gốc thay vì tự tìm kiếm của riêng bạn. Các trình vòng lặp bản địa nhanh hơn các giải pháp khác được trình bày.

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