Khi nào nên sử dụng iteritems () thay cho các mục ()?


153

Có hợp pháp để sử dụng items()thay vì iteritems()ở tất cả các nơi? Tại sao bị iteritems()xóa khỏi Python 3? Có vẻ như một phương pháp tuyệt vời và hữu ích. Lý do đằng sau nó là gì?

Chỉnh sửa: Để làm rõ, tôi muốn biết thành ngữ chính xác để lặp lại từ điển theo cách giống như trình tạo (một mục tại một thời điểm, không phải tất cả vào bộ nhớ) theo cách tương thích với cả Python 2 và Python 3 ?

Câu trả lời:


148

Trong Python 2.x - .items()trả về một danh sách các cặp (khóa, giá trị). Trong Python 3.x, .items()bây giờ là một itemviewđối tượng, mà ứng xử khác nhau - vì vậy nó được lặp kết thúc, hoặc cụ thể hóa ... Vì vậy, list(dict.items())là cần thiết cho những gì đã dict.items()bằng Python 2.x.

Python 2.7 cũng có một chút của một back-cảng để xử lý chủ chốt, trong đó bạn có viewkeys, viewitemsviewvaluesphương pháp, con người hữu ích nhất viewkeysmà cư xử giống như một set(mà bạn mong đợi từ một dict).

Ví dụ đơn giản:

common_keys = list(dict_a.viewkeys() & dict_b.viewkeys())

Sẽ cung cấp cho bạn một danh sách các khóa phổ biến, nhưng một lần nữa, trong Python 3.x - chỉ cần sử dụng .keys()thay thế.

Python 3.x đã thường được thực hiện để được nhiều hơn "lười biếng" - tức là mapbây giờ đã có hiệu quả itertools.imap, zipitertools.izipvv


96

dict.iteritemsđã bị xóa vì dict.itemsbây giờ điều đó dict.iteritemsđã làm trong python 2.x và thậm chí đã cải thiện nó một chút bằng cách biến nó thành một itemview.


64

Sáu thư viện giúp viết mã tương thích với cả python 2.5+ và python 3. Nó có một phương thức iteritems sẽ hoạt động trong cả python 2 và 3. Ví dụ:

import six

d = dict( foo=1, bar=2 )

for k, v in six.iteritems(d):
    print(k, v)

9

Vì tài liệu từ điển cho python 2python 3 sẽ cho bạn biết, trong python 2 itemstrả về một danh sách, trong khi iteritemstrả về một iterator.

Trong python 3, itemstrả về một khung nhìn , khá giống với một trình vòng lặp.

Nếu bạn đang sử dụng python 2, bạn có thể muốn sử dụng iteritemsnếu bạn đang xử lý các từ điển lớn và tất cả những gì bạn muốn làm là lặp lại các mục (không nhất thiết phải sao chép chúng vào danh sách)


Tôi hiểu rằng đó iteritemslà một trình vòng lặp, đó là lý do tại sao nó rất hữu ích. Tôi gần như không bao giờ muốn lặp lại từ điển như một danh sách. Vậy đâu là cách chính xác để lặp lại từ điển với trình tạo thứ gì đó giống như cách tương thích với cả Python 2 và 3?

3
@ user248237 for key in some_dicthoạt động trên cả hai - và 2to3công cụ sẽ dịch iteritems()để items()anyway ...
Jon Clements

1
@JonClements: đủ công bằng, mặc dù tôi luôn nghĩ for k in d: d[k]là dài dòng không cần thiết / unpythonic

6

Cũng như @Wessie ghi chú khác, dict.iteritems, dict.iterkeysdict.itervalues(trong đó trả về một iterator trong Python2.x) cũng như dict.viewitems, dict.viewkeysdict.viewvalues(mà lại xem các đối tượng trong Python2.x) đều được loại bỏ trong Python3.x

dict.items, dict.keysdict.valuesđược sử dụng để trả về một bản sao của danh sách từ điển trong Python2.x giờ trả về các đối tượng xem trong Python3.x, nhưng chúng vẫn không giống như iterator .

Nếu bạn muốn trả về một trình vòng lặp trong Python3.x, hãy sử dụng iter(dictview):

$ python3.3

>>> d = {'one':'1', 'two':'2'}
>>> type(d.items())
<class 'dict_items'>
>>>
>>> type(d.keys())
<class 'dict_keys'>
>>>
>>>
>>> ii = iter(d.items())
>>> type(ii)
<class 'dict_itemiterator'>
>>>
>>> ik = iter(d.keys())
>>> type(ik)
<class 'dict_keyiterator'>

Cái nào hiệu quả hơn khi người ta muốn thực hiện tra cứu ngược? xem đối tượng hay lặp?
tuổi thọ

6

Bạn không thể sử dụng itemsthay thế iteritemsở tất cả các nơi trong Python. Ví dụ: đoạn mã sau:

class C:
  def __init__(self, a):
    self.a = a
  def __iter__(self):
    return self.a.iteritems()

>>> c = C(dict(a=1, b=2, c=3))
>>> [v for v in c]
[('a', 1), ('c', 3), ('b', 2)]

sẽ bị hỏng nếu bạn sử dụng items:

class D:
  def __init__(self, a):
    self.a = a
  def __iter__(self):
    return self.a.items()

>>> d = D(dict(a=1, b=2, c=3))
>>> [v for v in d]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __iter__ returned non-iterator of type 'list'

Điều này cũng đúng với viewitems , có sẵn trong Python 3.

Ngoài ra, vì các mục trả về một bản sao danh sách các (key, value)cặp của từ điển , nên nó kém hiệu quả hơn, trừ khi bạn muốn tạo một bản sao.

Trong Python 2, tốt nhất là sử dụng iteritemsđể lặp lại. Công 2to3cụ này có thể thay thế nó itemsnếu bạn quyết định nâng cấp lên Python 3.


0

Tương lai.utils cho phép tương thích python 2 và 3

# Python 2 and 3: option 3
from future.utils import iteritems
heights = {'man': 185,'lady': 165}
for (key, value) in iteritems(heights):
    print(key,value)

>>> ('lady', 165)
>>> ('man', 185)

https://python-future.org/compiverse_idioms.html

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.