web-dev-qa-db-fra.com

Quelle est la difference entre dict.items () et dict.iteritems ()?

Existe-t-il des différences applicables entre dict.items() et dict.iteritems() ?

À partir de la docs Python:

dict.items(): Renvoie une copie de la liste du dictionnaire de paires (clé, valeur).

dict.iteritems(): Retourne un itérateur sur les paires du dictionnaire (clé, valeur).

Si je lance le code ci-dessous, chacun semble renvoyer une référence au même objet. Y a-t-il des différences subtiles qui me manquent?

#!/usr/bin/python

d={1:'one',2:'two',3:'three'}
print 'd.items():'
for k,v in d.items():
   if d[k] is v: print '\tthey are the same object' 
   else: print '\tthey are different'

print 'd.iteritems():'   
for k,v in d.iteritems():
   if d[k] is v: print '\tthey are the same object' 
   else: print '\tthey are different'   

Sortie:

d.items():
    they are the same object
    they are the same object
    they are the same object
d.iteritems():
    they are the same object
    they are the same object
    they are the same object
650
the wolf

Cela fait partie d'une évolution.

À l'origine, Python items() a créé une liste réelle de n-uplets et l'a renvoyée. Cela pourrait potentiellement prendre beaucoup de mémoire supplémentaire.

Ensuite, les générateurs ont été introduits dans le langage en général, et cette méthode a été réimplémentée en tant que méthode itérateur-générateur nommée iteritems(). L'original reste pour la compatibilité ascendante.

L’un des changements de Python 3 est que items() renvoie désormais des itérateurs, et une liste n’est jamais entièrement construite. La méthode iteritems() a également disparu, car items() dans Python 3 fonctionne comme viewitems() dans Python 2.7.

798
Keith

dict.items() renvoie une liste de 2-tuples ([(key, value), (key, value), ...]), alors que dict.iteritems() est un générateur qui produit 2-tuples. Le premier prend plus de temps et d'espace au début, mais l'accès à chaque élément est rapide, alors que le second prend moins de temps et d'espace, mais génère un peu plus de temps pour générer chaque élément.

En Py2.x

Les commandes dict.items(), dict.keys() et dict.values() renvoient une copie de la liste du dictionnaire de (k, v)paire, clés et valeurs. Cela peut prendre beaucoup de mémoire si la liste copiée est très grande.

Les commandes dict.iteritems(), dict.iterkeys() et dict.itervalues() renvoient un itérateur sur la paire (k, v) du dictionnaire, les clés et les valeurs.

Les commandes dict.viewitems(), dict.viewkeys() et dict.viewvalues() renvoient les ) objets de la vue , qui peuvent refléter les modifications apportées au dictionnaire. (Par exemple, si vous del un élément ou ajoutez une paire (k,v) dans le dictionnaire, l'objet de la vue peut automatiquement changer en même temps.)

$ python2.7

>>> d = {'one':1, 'two':2}
>>> type(d.items())
<type 'list'>
>>> type(d.keys())
<type 'list'>
>>> 
>>> 
>>> type(d.iteritems())
<type 'dictionary-itemiterator'>
>>> type(d.iterkeys())
<type 'dictionary-keyiterator'>
>>> 
>>> 
>>> type(d.viewitems())
<type 'dict_items'>
>>> type(d.viewkeys())
<type 'dict_keys'>

En Py3.x

Dans Py3.x, les choses sont plus propres, car il n'y a que dict.items(), dict.keys() et dict.values() disponible, qui renvoient les objets de vue exactement comme dict.viewitems() dans Py2. x l'a fait.

Mais

Comme @lvc l'a noté, un objet de vue n'est pas identique à itérateur , donc si vous voulez retourner un itérateur dans Py3.x, vous pouvez utiliser 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'>
62
YaOzI

Vous avez demandé: "Existe-t-il des différences applicables entre dict.items () et dict.iteritems ()"

Cela peut aider (pour Python 2.x):

>>> d={1:'one',2:'two',3:'three'}
>>> type(d.items())
<type 'list'>
>>> type(d.iteritems())
<type 'dictionary-itemiterator'>

Vous pouvez voir que d.items() renvoie une liste de tuples de la clé, des paires de valeurs et d.iteritems() renvoie un dictionnaire-itemiterator.

En tant que liste, d.items () peut être découpé en tranches:

>>> l1=d.items()[0]
>>> l1
(1, 'one')   # an unordered value!

Mais n'aurait pas de méthode __iter__:

>>> next(d.items())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list object is not an iterator

En tant qu'itérateur, d.iteritems () est not slice-capable:

>>> i1=d.iteritems()[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'dictionary-itemiterator' object is not subscriptable

Mais at-il __iter__:

>>> next(d.iteritems())
(1, 'one')               # an unordered value!

Donc, les articles eux-mêmes sont les mêmes - le conteneur qui les livre est différent. L'un est une liste, l'autre un itérateur (selon la version Python ...)

Les différences applicables entre dict.items () et dict.iteritems () sont donc identiques aux différences applicables entre une liste et un itérateur.

33
dawg

dict.items() renvoie la liste des n-uplets, et dict.iteritems() renvoie l'objet itérateur de Tuple dans le dictionnaire sous la forme (key,value). Les n-uplets sont les mêmes, mais le conteneur est différent.

dict.items() copie fondamentalement tous les dictionnaires dans une liste. Essayez d’utiliser le code suivant pour comparer les temps d’exécution de dict.items() et dict.iteritems(). Vous verrez la différence.

import timeit

d = {i:i*2 for i in xrange(10000000)}  
start = timeit.default_timer() #more memory intensive
for key,value in d.items():
    tmp = key + value #do something like print
t1 = timeit.default_timer() - start

start = timeit.default_timer()
for key,value in d.iteritems(): #less memory intensive
    tmp = key + value
t2 = timeit.default_timer() - start

Sortie dans ma machine:

Time with d.items(): 9.04773592949
Time with d.iteritems(): 2.17707300186

Cela montre clairement que dictionary.iteritems() est beaucoup plus efficace.

13
Prabhu

Si tu as

dict = {key1:value1, key2:value2, key3:value3,...}

Dans Python 2, dict.items() copie chaque n-uplet et renvoie la liste des n-uplets du dictionnaire, à savoir [(key1,value1), (key2,value2), ...]. Les implications sont que le dictionnaire entier est copié dans une nouvelle liste contenant des nuplets

dict = {i: i * 2 for i in xrange(10000000)}  
# Slow and memory hungry.
for key, value in dict.items():
    print(key,":",value)

dict.iteritems() renvoie l'itérateur d'élément de dictionnaire. La valeur de l'élément renvoyé est également la même que (key1,value1), (key2,value2), ..., mais il ne s'agit pas d'une liste. Ceci est uniquement un objet itérateur d'élément de dictionnaire. Cela signifie moins d’utilisation de la mémoire (50% de moins).

  • Listes sous forme d'instantanés mutables: d.items() -> list(d.items())
  • Objets Itérateur: d.iteritems() -> iter(d.items())

Les tuples sont les mêmes. Vous avez comparé des n-uplets dans chacun pour obtenir le même résultat.

dict = {i: i * 2 for i in xrange(10000000)}  
# More memory efficient.
for key, value in dict.iteritems():
    print(key,":",value)

Dans Python, dict.items() renvoie un objet itérateur. dict.iteritems () est supprimé, il n'y a donc plus de problème.

4
Hary Bakta

dict.iteritems(): vous donne un itérateur. Vous pouvez utiliser l'itérateur dans d'autres modèles en dehors de la boucle.

student = {"name": "Daniel", "student_id": 2222}

for key,value in student.items():
    print(key,value)

('student_id', 2222)
('name', 'Daniel')

for key,value in student.iteritems():
    print(key,value)

('student_id', 2222)
('name', 'Daniel')

studentIterator = student.iteritems()

print(studentIterator.next())
('student_id', 2222)

print(studentIterator.next())
('name', 'Daniel')
0
ethplumber

Si vous voulez un moyen d'itérer les paires d'éléments d'un dictionnaire qui fonctionne avec Python 2 et 3, essayez quelque chose comme ceci:

DICT_ITER_ITEMS = (lambda d: d.iteritems()) if hasattr(dict, 'iteritems') else (lambda d: iter(d.items()))

Utilisez-le comme ceci:

for key, value in DICT_ITER_ITEMS(myDict):
    # Do something with 'key' and/or 'value'.
0
R. Navega

dict.iteritems est parti en Python3.x, donc utilisez iter(dict.iitems()) pour obtenir la même sortie et la même allocation mémoire.

0
Tessaracter