Erreur: "L'objet 'dict' n'a pas d'attribut 'iteritems'"

436

J'essaie d'utiliser NetworkX pour lire un fichier de formes et utiliser la fonction write_shp()pour générer les fichiers de formes qui contiendront les nœuds et les bords, mais lorsque j'essaie d'exécuter le code, cela me donne l'erreur suivante:

Traceback (most recent call last):   File
"C:/Users/Felipe/PycharmProjects/untitled/asdf.py", line 4, in
<module>
    nx.write_shp(redVial, "shapefiles")   File "C:\Python34\lib\site-packages\networkx\readwrite\nx_shp.py", line
192, in write_shp
    for key, data in e[2].iteritems(): AttributeError: 'dict' object has no attribute 'iteritems'

J'utilise Python 3.4 et j'ai installé NetworkX via l'installation de pip.

Avant cette erreur, il m'en avait déjà donné un autre qui disait "xrange n'existe pas" ou quelque chose comme ça, alors je l'ai recherché et je suis passé xrangeau rangefichier nx_shp.py, qui semblait le résoudre.

D'après ce que j'ai lu, cela pourrait être lié à la version Python (Python2 vs Python3).

friveraa
la source
234
Python 3 renommé dict.iteritems -> dict.items.
Blender
1
oh wow je me sens tellement idiot en ce moment, merci pour la réponse
friveraa
6
@Blender: Non, il n'a pas renomme iteritemsà items. Le premier vous a donné un itérateur (et 3.x n'a pas une telle méthode); ce dernier vous donne une vue (qui a été rétroportée à 2,7 comme viewitems).
abarnert
Cela peut ou non être la page équivalente à ce à quoi l'OP était lié à l'origine: networkx.github.io/documentation/latest/reference/readwrite/…
Nathan Arthur

Réponses:

881

Comme vous êtes en python3, utilisez dict.items()au lieu dedict.iteritems()

iteritems() a été supprimé en python3, vous ne pouvez donc plus utiliser cette méthode.

Jetez un oeil à la section Python 3.0 Wiki Built-in Changes , où il est indiqué:

Suppression dict.iteritems(), dict.iterkeys()et dict.itervalues().

Au lieu de cela: l' utilisation dict.items(), dict.keys()et dict.values() respectivement.

rafaelc
la source
Une discussion plus approfondie à ce sujet est officiellement enregistrée dans le PEP 469 . L'approche recommandée semble être d'utiliser à la place la iteritemsfonction des modules future.utilsou six.
Mack
33

En Python2 , nous avions .items()et .iteritems()dans les dictionnaires. dict.items()a renvoyé la liste des tuples dans le dictionnaire [(k1,v1),(k2,v2),...]. Il a copié tous les tuples dans le dictionnaire et créé une nouvelle liste. Si le dictionnaire est très volumineux, la mémoire a un impact très important.

Ils ont donc créé dict.iteritems()dans les versions ultérieures de Python2. Cela a renvoyé l'objet itérateur. Le dictionnaire entier n'a pas été copié, ce qui réduit la consommation de mémoire. Les personnes utilisant Python2sont enseignées à utiliser dict.iteritems()plutôt qu'à des .items()fins d'efficacité comme expliqué dans le code suivant.

import timeit

d = {i:i*2 for i in xrange(10000000)}  
start = timeit.default_timer()
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():
    tmp = key + value
t2 = timeit.default_timer() - start

Production:

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

En Python3 , ils voulaient le rendre plus efficace, donc déplacé dictionary.iteritems()vers dict.items()et supprimé .iteritems()car il n'était plus nécessaire.

Vous avez utilisé dict.iteritems()en Python3sorte qu'il a échoué. Essayez d' utiliser dict.items()qui a la même fonctionnalité que dict.iteritems()de Python2. Il s'agit d'un petit problème de migration de Python2vers Python3.

Prabhu
la source
5

J'ai eu un problème similaire (en utilisant 3.5) et y ai perdu une demi-journée mais voici quelque chose qui fonctionne - je suis à la retraite et j'apprends juste Python afin que je puisse aider mon petit-fils (12) avec.

mydict2={'Atlanta':78,'Macon':85,'Savannah':72}
maxval=(max(mydict2.values()))
print(maxval)
mykey=[key for key,value in mydict2.items()if value==maxval][0]
print(mykey)
YEILDS; 
85
Macon
Big Daddy
la source
5

En Python2, dictionary.iteritems()est plus efficace qu'en dictionary.items()Python3, la fonctionnalité de dictionary.iteritems()a été migrée vers dictionary.items()et iteritems()est supprimée. Vous obtenez donc cette erreur.

Utilisation dict.items()en Python3 qui est identique à dict.iteritems()Python2.


la source
-1

Le but de .iteritems()était d'utiliser moins d'espace mémoire en produisant un résultat à la fois lors de la boucle. Je ne sais pas pourquoi la version Python 3 ne prend pas en charge iteritems()bien qu'elle se soit avérée efficace que.items()

Si vous souhaitez inclure un code qui prend en charge les versions PY 2 et 3,

try:
    iteritems
except NameError:
    iteritems = items

Cela peut être utile si vous déployez votre projet dans un autre système et que vous n'êtes pas sûr de la version PY.

DivyaMaheswaran
la source
-1

Comme l'a répondu RafaelC, Python 3 a renommé dict.iteritems -> dict.items. Essayez une autre version de package. Cette liste répertorie les packages disponibles:

python -m pip install yourOwnPackageHere==

Ensuite, réexécutez avec la version que vous allez essayer après == pour installer / changer de version

Punnerud
la source