Pytanie Iteracja po słownikach za pomocą pętli "for"


Jestem nieco zaintrygowany następującym kodem:

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:
    print key, 'corresponds to', d[key]

Czego nie rozumiem, to key część. W jaki sposób Python rozpoznaje, że potrzebuje tylko odczytać klucz ze słownika? Jest key specjalne słowo w Pythonie? Czy jest to po prostu zmienna?


2112
2017-07-20 22:27


pochodzenie




Odpowiedzi:


key jest po prostu nazwą zmiennej.

for key in d:

będzie po prostu zapętlać klawisze w słowniku, a nie klawisze i wartości. Aby zapętlić zarówno klucz, jak i wartość, można użyć:

Dla Python 2.x:

for key, value in d.iteritems():

W przypadku Python 3.x:

for key, value in d.items():

Aby przetestować samodzielnie, zmień słowo key do poop.

W przypadku Python 3.x, iteritems() został zastąpiony po prostu items(), który zwraca widok podobny do zestawu wspieranego przez dict, np iteritems() ale jeszcze lepiej. Jest to również dostępne w wersji 2.7 jako viewitems().

Operacja items() będzie działać zarówno dla 2, jak i 3, ale w 2 zwróci listę słownika (key, value) pary, które nie będą odzwierciedlać zmian w dyktowaniu, które nastąpią po items() połączenie. Jeśli chcesz zachować zachowanie 2.x w 3.x, możesz zadzwonić list(d.items()).


3804
2017-07-20 22:29



Dodanie przeoczonego powodu, aby nie uzyskiwać dostępu do wartości takich jak ta: d [klucz] wewnątrz pętli for powoduje, że klucz jest ponownie mieszany (aby uzyskać wartość). Gdy słownik jest duży, dodatkowy skrót zostanie dodany do czasu ogólnego. Jest to omówione w wykładzie technicznym Raymonda Hettingera youtube.com/watch?v=anrOzOapJ2E - Harisankar Krishna Swamy
w Pythonie 3.6 zmieniono jako d.items() - Decoded
Dobra odpowiedź, a prawdziwy geniusz polega na zmianie key do poop. Dzięki za wgląd, @sberry! - Mike Williamson


Nie jest tak, że klucz jest specjalnym słowem, ale słowniki te implementują protokół iteratora. Możesz to zrobić w swojej klasie, np. widzieć to pytanie jak zbudować iteratory klas.

W przypadku słowników jest zaimplementowana na poziomie C. Szczegóły są dostępne w PEP 234. W szczególności sekcja zatytułowana "Iteratory słownikowe":

  • Słowniki implementują slot tp_iter, który zwraca efektywność   iterator, który iteruje po kluczach słownika. [...] To   oznacza, że ​​możemy pisać

    for k in dict: ...
    

    co jest równoważne, ale znacznie szybsze niż

    for k in dict.keys(): ...
    

    pod warunkiem ograniczenia modyfikacji słownika   (albo przez pętlę albo przez inny wątek) nie są naruszane.

  • Dodaj metody do słowników, które zwracają różne rodzaje   iteratory jawnie:

    for key in dict.iterkeys(): ...
    
    for value in dict.itervalues(): ...
    
    for key, value in dict.iteritems(): ...
    

    To znaczy że for x in dict jest skrótem dla for x in dict.iterkeys().


325
2017-07-20 23:52



W python3 dict.iterkeys (), dykt.itervalues ​​() i dict.iteritems () nie są już obsługiwane. Zamiast tego należy użyć funkcji dict.keys (), dict.values ​​() i dict.items (). - Sadik


Iterowanie nad a dict iteruje za pomocą kluczy w dowolnej kolejności, jak widać tutaj:

Edycja: (To jest już nie w przypadku Python3.6, ale zauważ, że jest Niegwarantowane zachowanie jeszcze)

>>> d = {'x': 1, 'y': 2, 'z': 3} 
>>> list(d)
['y', 'x', 'z']
>>> d.keys()
['y', 'x', 'z']

Dla przykładu, lepiej jest użyć dict.items():

>>> d.items()
[('y', 2), ('x', 1), ('z', 3)]

Daje ci to listę krotek. Kiedy pętli nad nimi w ten sposób, każda krotka jest rozpakowywana k i v automatycznie:

for k,v in d.items():
    print(k, 'corresponds to', v)

Za pomocą k i v jako nazwy zmiennych podczas zapętlania nad dict jest dość powszechne, jeśli treść pętli to tylko kilka linii. W przypadku bardziej skomplikowanych pętli dobrym pomysłem może być użycie bardziej opisowych nazw:

for letter, number in d.items():
    print(letter, 'corresponds to', number)

Dobrym zwyczajem jest używanie zwyczajów formatowania:

for letter, number in d.items():
    print('{0} corresponds to {1}'.format(letter, number))

151
2017-07-21 01:27



Z informacji o wydaniu Pythona 3.7: "Charakterystyka obiektów dictowych w kolejności wstawiania jest teraz oficjalną częścią specyfikacji języka Python." - Gregory Arenius


key jest po prostu zmienną.

Dla Python2.X:

d = {'x': 1, 'y': 2, 'z': 3} 
for my_var in d:
    print my_var, 'corresponds to', d[my_var]

... albo lepiej,

d = {'x': 1, 'y': 2, 'z': 3} 
for the_key, the_value in d.iteritems():
    print the_key, 'corresponds to', the_value

Dla Python3.X:

d = {'x': 1, 'y': 2, 'z': 3} 
for the_key, the_value in d.items():
    print(the_key, 'corresponds to', the_value)

44
2017-07-20 23:49





Podczas iteracji poprzez słowniki za pomocą for .. in ..-syntax, zawsze iteruje po klawiszach (wartości są dostępne za pomocą dictionary[key]).

Aby powtórzyć parami klucz-wartość, użyj for k,v in s.iteritems().


39
2017-07-20 22:29



Zauważ, że dla Pythona 3 jest items() zamiast iteritems() - Andreas Fester


Jest to bardzo powszechny idiom pętli. in jest operatorem. Na kiedy używać for key in dict i kiedy to musi być for key in dict.keys() widzieć Artykuł Idiomatic Pythona autorstwa Davida Goodgera.


20
2017-07-20 22:42



Jak czytam te sekcje na temat in, częścią operatora jest gdzie sprawdzasz istnienie. Może lepiej to usuń in is an operator Informacja. - Wolf


Możesz użyć tego:

for key,val in d.items():
    print key, 'is the key for ', val

9
2018-01-14 14:42



To trochę stary post - Sadi
@Sadi Czy to już nie prawda? - Basj


Mam przypadek użycia, w którym muszę wykonać iterację poprzez dyktando, aby uzyskać klucz, parę wartości, a także indeks wskazujący, gdzie jestem. Tak to robię:

d = {'x': 1, 'y': 2, 'z': 3} 
for i, (key, value) in enumerate(d.items()):
   print(i, key, value)

Zauważ, że nawiasy wokół klucza, wartość jest ważna, bez nawiasów, otrzymasz ValueError "za mało wartości do rozpakowania".


6
2018-05-25 13:42





Iteracja po słownikach za pomocą pętli "for"

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:
    ...

W jaki sposób Python rozpoznaje, że potrzebuje tylko odczytać klucz z pliku   słownik? Czy klucz jest specjalnym słowem w Pythonie? A może po prostu   zmienna?

To nie tylko for pętle. Ważnym słowem jest tutaj "iteracja".

Słownik to mapowanie kluczy do wartości:

d = {'x': 1, 'y': 2, 'z': 3} 

Za każdym razem, gdy sprawdzamy, iterujemy klucze. Nazwa zmiennej key ma jedynie charakter opisowy i jest całkiem odpowiedni do tego celu.

Zdarza się to w zrozumieniu listy:

>>> [k for k in d]
['x', 'y', 'z']

Dzieje się tak, gdy przekazujemy słownik do listy (lub dowolnego innego obiektu typu kolekcji):

>>> list(d)
['x', 'y', 'z']

Sposób, w jaki Python wykonuje iteracje, w kontekście, w którym musi, wywołuje metodę __iter__ metoda obiektu (w tym przypadku słownik), która zwraca iterator (w tym przypadku obiekt keyiterator):

>>> d.__iter__()
<dict_keyiterator object at 0x7fb1747bee08>

Nie powinniśmy używać tych specjalnych metod sami, zamiast tego użyj odpowiedniej wbudowanej funkcji, aby je wywołać, iter:

>>> key_iterator = iter(d)
>>> key_iterator
<dict_keyiterator object at 0x7fb172fa9188>

Iteratory mają __next__ metoda - ale nazywamy to funkcją wbudowaną, next:

>>> next(key_iterator)
'x'
>>> next(key_iterator)
'y'
>>> next(key_iterator)
'z'
>>> next(key_iterator)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

Kiedy iterator jest wyczerpany, podnosi się StopIteration. Tak Python wie, jak wyjść z a for pętli lub rozumienia listy, wyrażeń generujących lub innych iteracyjnych kontekstów. Raz wznosi się iterator StopIteration zawsze go podniesie - jeśli chcesz powtórzyć, potrzebujesz nowego.

>>> list(key_iterator)
[]
>>> new_key_iterator = iter(d)
>>> list(new_key_iterator)
['x', 'y', 'z']

Wracając do dyktatury

Widzieliśmy dyktowanie iteracyjne w wielu kontekstach. Widzieliśmy, że za każdym razem, gdy powtarzamy dykcję, otrzymujemy klucze. Powrót do oryginalnego przykładu:

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:

Jeśli zmienimy nazwę zmiennej, nadal otrzymamy klucze. Spróbujmy:

>>> for each_key in d:
...     print(each_key, '=>', d[each_key])
... 
x => 1
y => 2
z => 3

Jeśli chcemy iterować wartości, musimy użyć .values metoda dyktowania lub dla obu, .items:

>>> list(d.values())
[1, 2, 3]
>>> list(d.items())
[('x', 1), ('y', 2), ('z', 3)]

W podanym przykładzie bardziej efektywne byłoby iterowanie nad takimi elementami:

for a_key, corresponding_value in d.items():
    print(a_key, corresponding_value)

Ale dla celów akademickich przykład pytania jest w porządku.


4
2018-06-21 02:51