2012-12-21 6 views
92

Ist es legitim, items() anstelle von iteritems() an allen Orten zu verwenden? Warum wurde iteritems() aus Python 3 entfernt? Scheint wie eine tolle und nützliche Methode. Was ist der Grund dafür?iteritems in Python

EDIT: Um zu klären, möchte ich wissen, was ist das richtige Idiom für das Iterieren über ein Wörterbuch auf eine Generator-ähnliche Weise (ein Element zu einer Zeit, nicht alle in den Speicher) in einer Weise, die mit beiden Python kompatibel ist 2 und Python 3?

Antwort

89

In Python 2.x - .items() gab eine Liste von Paaren (Schlüssel, Wert) zurück. In Python 3.x, .items() ist jetzt ein itemview Objekt, das sich anders verhält - so dass es hat, um iteriert zu werden, oder materialisiert ... So ist list(dict.items()) erforderlich für was war dict.items() in Python 2.x.

Python 2.7 hat auch ein bisschen von einem Back-Port für die Schlüsselverwaltung, dass Sie viewkeys, viewitems und viewvalues Methoden, die die nützlichsten viewkeys sein, welche mehr verhält sich wie ein set (was man von einem dict erwarten würde,).

Einfaches Beispiel:

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

Werden Sie eine Liste der gemeinsamen Schlüssel, aber auch hier in Python 3.x - nur .keys() stattdessen verwenden.

Python 3.x wurde im allgemeinen als „faul“ gemacht worden - das heißt map jetzt effektiv itertools.imap, zipitertools.izip ist usw.

53

dict.iteritems wurde entfernt, weil dict.items jetzt tut das, was dict.iteritems in Python 2.x tat und es sogar ein wenig verbessert, indem es eine itemview.

5

Als Wörterbuch Dokumentation für python 2 und python 3 würden Sie sagen, in Python 2 items gibt eine Liste zurück, während iteritems einen Iterator zurückgibt.

In Python 3 gibt items eine view zurück, die ziemlich genau wie ein Iterator ist.

Wenn Sie mit Python 2, können Sie iteritems an Benutzer möchten, wenn Sie mit großen Wörterbücher zu tun und alles, was Sie wollen, ist Iterierte über die Elemente (nicht unbedingt, sie zu einer Liste kopieren)

+0

Ich verstehe, dass "iteritems" ein Iterator ist, weshalb es so nützlich ist. Ich möchte fast nie über ein Wörterbuch als Liste iterieren. Also, was ist der richtige Weg, um mit etwas Generator über Wörterbuch zu iterieren, so wie es mit Python 2 und 3 kompatibel ist? – user248237dfsf

+2

@ user248237 'für Schlüssel in some_dict' funktioniert auf beiden - und das' 2to3' Werkzeug übersetzt 'iteritems()' in 'items()' auf jeden Fall ... –

+1

@JonClements: fair genug, obwohl ich immer dachte '' für k in d: d [k] '' ist unnötig ausführlich/unpythonisch – user248237dfsf

2

Wie @Wessie erwähnt, dict.iteritems, dict.iterkeys und dict.itervalues (die einen Iterator in python2.x Rück) sowie dict.viewitems, dict.viewkeys und dict.viewvalues (die Ansicht zurückzukehren in python2.x Objekte) wurden alle in Python3.x entfernt

Und dict.items, dict.keys und dict.values verwendet, um eine Kopie des Wörterbuch der Liste in Python2.x zurückzukehren Ansicht jetzt zurückzukehren Objekte in Python3.x, aber sie sind nicht immer noch die gleiche wie Iterator.

Wenn Sie eine Iterator in Python3.x zurückkehren möchten, verwenden :

$ 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'> 
3

Sie nicht items statt iteritems in allen Orten in Python verwenden können. Zum Beispiel der folgende Code:

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

brechen, wenn Sie items verwenden:

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' 

Das gleiche gilt für viewitems, die in Python 3.

Da auch items verfügbar Gibt eine Kopie der Wörterbuchliste von (key, value) Paaren zurück, es ist weniger effizient, es sei denn, Sie möchten trotzdem eine Kopie erstellen. In Python 2 verwenden Sie am besten iteritems für die Iteration. Das 2to3 Werkzeug kann es mit items ersetzen, wenn Sie schon einmal in Python 3.

38

The six library hilft mit dem Schreiben von Code zu aktualisieren entscheiden, das sowohl mit Python kompatibel ist 2.5+ und Python 3. Es hat eine iteritems Methode verfügt, die sowohl in Python arbeiten 2 und 3. Beispiel:

from __future__ import division, absolute_import, print_function, unicode_literals 
import six 

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

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