Kapan seharusnya iteritems () digunakan alih-alih item ()?

153

Apakah sah untuk digunakan items()daripada iteritems()di semua tempat? Mengapa iteritems()dihapus dari Python 3? Sepertinya metode yang hebat dan berguna. Apa alasan di baliknya?

Sunting: Untuk memperjelas, saya ingin tahu apa idiom yang benar untuk iterasi melalui kamus dengan cara seperti generator (satu item pada satu waktu, tidak semua ke memori) dengan cara yang kompatibel dengan Python 2 dan Python 3 ?

martineau
sumber

Jawaban:

148

Dalam Python 2.x - .items()mengembalikan daftar pasangan (kunci, nilai). Dalam Python 3.x, .items()sekarang menjadi itemviewobjek, yang berperilaku berbeda - sehingga memiliki untuk mengulangi lebih, atau terwujud ... Jadi, list(dict.items())diperlukan untuk apa yang dict.items()Python 2.x.

Python 2.7 juga memiliki sedikit back-port untuk penanganan kunci, di mana Anda memiliki viewkeys, viewitemsdan viewvaluesmetode, makhluk viewkeysyang paling berguna yang berperilaku lebih seperti set(yang Anda harapkan dari a dict).

Contoh sederhana:

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

Akan memberi Anda daftar kunci umum, tetapi sekali lagi, dengan Python 3.x - gunakan .keys()saja.

Python 3.x secara umum dibuat lebih "malas" - yaitu mapsekarang efektif itertools.imap, zipsedang itertools.izip, dll.

Jon Clements
sumber
96

dict.iteritemstelah dihapus karena dict.itemssekarang hal itu dict.iteritemsdilakukan dengan python 2.x dan bahkan memperbaikinya sedikit dengan membuatnya menjadi itemview.

Wessie
sumber
64

Enam perpustakaan membantu dengan menulis kode yang kompatibel dengan kedua python 2.5+ dan python 3. Ini memiliki metode iteritems yang akan bekerja di kedua python 2 dan 3. Contoh:

import six

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

for k, v in six.iteritems(d):
    print(k, v)
Dean Serenevy
sumber
9

Sebagai dokumentasi kamus untuk python 2 dan python 3 akan memberitahu Anda, di python 2 itemsmengembalikan daftar, sementaraiteritems mengembalikan iterator.

Dalam python 3, itemsmengembalikan tampilan , yang hampir sama dengan iterator.

Jika Anda menggunakan python 2, Anda mungkin ingin pengguna iteritemsjika Anda berurusan dengan kamus besar dan semua yang ingin Anda lakukan adalah beralih ke item (tidak perlu menyalinnya ke daftar)

goncalopp
sumber
Saya mengerti itu iteritemsadalah iterator, oleh karena itu sangat berguna. Saya hampir tidak pernah ingin beralih ke kamus sebagai daftar. Jadi apa cara yang benar untuk beralih ke kamus dengan sesuatu seperti generator dengan cara yang kompatibel dengan Python 2 dan 3?
3
@ user248237 for key in some_dictbekerja pada keduanya - dan 2to3alat ini akan menerjemahkan iteritems()untuk items()tetap ...
Jon Clements
1
@ JonClements: cukup adil, meskipun saya selalu berpikir for k in d: d[k]tidak perlu verbose / unpythonic
6

Sama seperti @Wessie perhatikan dict.iteritems,, dict.iterkeysdan dict.itervalues(yang mengembalikan iterator dengan Python2.x) juga dict.viewitems, dict.viewkeysdan dict.viewvalues(yang mengembalikan objek tampilan dalam Python2.x) semuanya dihapus dalam Python3.x

Dan dict.items, dict.keysdan dict.valuesdigunakan untuk mengembalikan salinan daftar kamus di Python2.x sekarang mengembalikan objek tampilan di Python3.x, tetapi mereka masih tidak sama dengan iterator .

Jika Anda ingin mengembalikan iterator di Python3.x, gunakan 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'>
YaOzI
sumber
Mana yang lebih efisien ketika seseorang ingin melakukan pencarian terbalik? lihat objek atau iterator?
lifebalance
6

Anda tidak dapat menggunakan itemsbukannya iteritemsdi semua tempat di Python. Misalnya, kode berikut:

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)]

akan rusak jika Anda menggunakan 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'

Hal yang sama berlaku untuk viewitems , yang tersedia dalam Python 3.

Juga, karena item mengembalikan salinan daftar (key, value)pasangan kamus , itu kurang efisien, kecuali jika Anda tetap ingin membuat salinan.

Dalam Python 2, yang terbaik adalah menggunakan iteritemsuntuk iterasi. The 2to3alat bisa menggantinya dengan itemsjika Anda pernah memutuskan untuk meng-upgrade ke Python 3.

Musim Dingin Florian
sumber
0

future.utils memungkinkan untuk kompatibilitas python 2 dan 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/compatible_idioms.html

Daniel
sumber