Błąd: „Obiekt„ dict ”nie ma atrybutu„ iteritems ””


436

Próbuję użyć NetworkX do odczytania pliku Shapefile i użyć funkcji write_shp()do wygenerowania plików Shapefile, które będą zawierać węzły i krawędzie, ale gdy próbuję uruchomić kod, pojawia się następujący błąd:

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'

Używam Python 3.4 i zainstalowałem NetworkX przez pip install.

Przed tym błędem dał mi już inny, który powiedział „xrange nie istnieje” lub coś w tym rodzaju, więc spojrzałem na to i po prostu zmieniłem xrangena rangew pliku nx_shp.py, który wydawał się go rozwiązać.

Z tego, co przeczytałem, może to być związane z wersją Pythona (Python2 vs Python3).


231
Nazwa Python 3 została zmieniona dict.iteritems -> dict.items.
Blender

1
och wow, czuję się teraz tak głupio, dzięki za odpowiedź
friveraa

6
@Blender: Nie, to nie zmiana nazwy iteritemsna items. Ten pierwszy dał ci iterator (a 3.x nie ma takiej metody); ten ostatni daje widok (który został przeniesiony do wersji 2.7 as viewitems).
abarnert


To może być, ale nie musi, odpowiednik strony, do której pierwotnie linkował
Nathan Arthur

Odpowiedzi:


881

Gdy jesteś w Python3, użyj dict.items()zamiastdict.iteritems()

iteritems() został usunięty w python3, więc nie możesz już używać tej metody.

Spójrz na sekcję Zmiany wbudowane w Python 3.0 Wiki , gdzie jest powiedziane:

Usunięte dict.iteritems(), dict.iterkeys()i dict.itervalues().

Zamiast: użycie dict.items(), dict.keys()oraz dict.values() odpowiednio.


Dalsza dyskusja na ten temat jest oficjalnie zapisana w PEP 469 . Zalecanym podejściem wydaje się być użycie zamiast tego iteritemsfunkcji future.utilslub sixmodułów.
Mack

33

W Python2 mieliśmy .items()i .iteritems()słowniki. dict.items()zwróciła listę krotek w słowniku [(k1,v1),(k2,v2),...]. Skopiował wszystkie krotki ze słownika i utworzył nową listę. Jeśli słownik jest bardzo duży, ma to duży wpływ na pamięć.

Więc stworzyli dict.iteritems()w późniejszych wersjach Python2. Zwrócił obiekt iteratora. Cały słownik nie został skopiowany, więc zużycie pamięci jest mniejsze. Ludzie używający Python2są uczeni używania dict.iteritems()zamiast .items()wydajności, jak wyjaśniono w poniższym kodzie.

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

Wynik:

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

W Python3 chcieli sprawić, by był bardziej wydajny, więc przenieśli się dictionary.iteritems()do niego dict.items()i usunęli, .iteritems()ponieważ nie był już potrzebny.

Użyłeś dict.iteritems()w Python3tak nie udało. Spróbuj użyć dict.items()która ma taką samą funkcjonalność jak dict.iteritems()z Python2. Jest to niewielki problem z migracją od Python2do Python3.


5

Miałem podobny problem (przy użyciu 3.5) i straciłem 1/2 dnia, ale oto coś, co działa - jestem na emeryturze i dopiero uczę się języka Python, aby pomóc w tym mojemu wnukowi (12).

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

5

W Python2 dictionary.iteritems()jest bardziej wydajny niż dictionary.items()w Python3, funkcja dictionary.iteritems()została przeniesiona do dictionary.items()i iteritems()została usunięta. Otrzymujesz ten błąd.

Użyj dict.items()w Python3, który jest taki sam jak dict.iteritems()w Python2.


-1

Celem .iteritems()było wykorzystanie mniejszej ilości pamięci, dając jeden wynik na raz podczas zapętlania. Nie jestem pewien, dlaczego wersja Python 3 nie obsługuje, iteritems()chociaż okazało się, że jest wydajniejsza niż.items()

Jeśli chcesz dołączyć kod, który obsługuje zarówno wersję PY 2, jak i 3,

try:
    iteritems
except NameError:
    iteritems = items

Może to pomóc, jeśli wdrożysz projekt w innym systemie i nie masz pewności co do wersji PY.


-1

Jak odpowiedział RafaelC, Python 3 zmienił nazwę na dict.iteritems -> dict.items. Wypróbuj inną wersję pakietu. Spowoduje to wyświetlenie listy dostępnych pakietów:

python -m pip install yourOwnPackageHere==

Następnie uruchom ponownie wersję, którą spróbujesz po ==, aby zainstalować / zmienić wersję

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.