Jestem trochę zdziwiony następującym kodem:
d = {'x': 1, 'y': 2, 'z': 3}
for key in d:
print key, 'corresponds to', d[key]
To, czego nie rozumiem, to key
porcja. Jak Python rozpoznaje, że wystarczy tylko odczytać klucz ze słownika? Czy key
w Pythonie jest specjalne słowo? Czy jest to po prostu zmienna?
python
python-2.7
dictionary
TopChef
źródło
źródło
Odpowiedzi:
key
to tylko nazwa zmiennej.po prostu zapętli klawisze w słowniku, a nie klucze i wartości. Aby zapętlić zarówno klucz, jak i wartość, możesz użyć:
W przypadku Python 3.x:
W przypadku Python 2.x:
Aby sprawdzić sam, zmień słowo
key
napoop
.W Pythonie 3.x
iteritems()
został zastąpiony przez po prostuitems()
, który zwraca widok podobny do zestawu, wspierany przez dyktat,iteritems()
ale jeszcze lepszy. Jest to również dostępne w wersji 2.7 jakoviewitems()
.Operacja
items()
będzie działać zarówno dla 2, jak i 3, ale w 2 zwróci listę(key, value)
par słownika , która nie będzie odzwierciedlała zmian w dyktandzie, które nastąpiły poitems()
wywołaniu. Jeśli chcesz zachować 2.x w 3.x, możesz zadzwonićlist(d.items())
.źródło
sorted
są potrzebne do ich ustabilizowania.Keys and values are iterated over in insertion order.
[ docs.python.org/3/library/…Nie chodzi o to, że klucz jest słowem specjalnym, ale o to, że słowniki implementują protokół iteratora. Możesz to zrobić w swojej klasie, np. Zobacz to pytanie, jak zbudować iteratory klas.
W przypadku słowników jest on implementowany na poziomie C. Szczegóły są dostępne w PEP 234 . W szczególności sekcja zatytułowana „Iteratory słownikowe”:
W Pythonie 3
dict.iterkeys()
,dict.itervalues()
idict.iteritems()
nie są już obsługiwane. Zastosowaniedict.keys()
,dict.values()
adict.items()
zamiast tego.źródło
Iteracja po
dict
iteracji przez klucze w żadnej określonej kolejności, jak widać tutaj:Edycja: (Nie dotyczy to już Python3.6 , ale zauważ, że nie jest to jeszcze zagwarantowane zachowanie)
Na przykład lepiej jest użyć
dict.items()
:To daje listę krotek. Gdy zapętlisz je w ten sposób, każda krotka jest rozpakowywana
k
iv
automatycznie:Używanie
k
iv
jako nazw zmiennych podczas zapętlania nad adict
jest dość powszechne, jeśli treść pętli składa się tylko z kilku linii. W przypadku bardziej skomplikowanych pętli dobrym pomysłem może być użycie bardziej opisowych nazw:Warto przyzwyczaić się do używania ciągów formatu:
źródło
key
jest po prostu zmienną.W przypadku Python2.X :
... albo lepiej,
W przypadku Python3.X :
źródło
Podczas iteracji przez słowniki za pomocą opcji
for .. in ..
-syntax zawsze iteruje się po klawiszach (wartości są dostępne za pomocądictionary[key]
).Aby iterować po parach klucz-wartość, w Pythonie 2
for k,v in s.iteritems()
i Pythonie 3for k,v in s.items()
.źródło
items()
zamiastiteritems()
Jest to bardzo popularny idiom pętli.
in
jest operatorem. Kiedyfor key in dict
i kiedy należy go użyć,for key in dict.keys()
zobacz artykuł Idiomatic Pythona Davida Goodgera (zarchiwizowana kopia) .źródło
in
, część dla operatora jest miejscem, w którym sprawdzasz istnienie . Może lepiej usuń tein is an operator
informacje.To nie tylko
for
pętle. Ważnym słowem jest tutaj „iteracja”.Słownik to mapowanie kluczy na wartości:
Za każdym razem, gdy wykonujemy iterację, iterujemy po klawiszach. Nazwa zmiennej
key
ma jedynie charakter opisowy - i jest całkiem trafna do tego celu.Dzieje się tak w przypadku zrozumienia listy:
Dzieje się tak, gdy przekazujemy słownik do listy (lub dowolnego innego obiektu typu kolekcji):
Sposób, w jaki Python wykonuje iterację, w kontekście, w którym musi, wywołuje
__iter__
metodę obiektu (w tym przypadku słownika), który zwraca iterator (w tym przypadku obiekt keyiteratora):Nie powinniśmy sami korzystać z tych specjalnych metod, zamiast tego użyj odpowiedniej funkcji wbudowanej, aby ją wywołać
iter
:Iteratory mają
__next__
metodę - ale nazywamy ją wbudowaną funkcjąnext
:Kiedy iterator jest wyczerpany, podnosi się
StopIteration
. W ten sposób Python wie, jak wyjść zfor
pętli, ze zrozumienia listy, wyrażenia generatora lub dowolnego innego kontekstu iteracyjnego. Gdy iterator podniesieStopIteration
, zawsze go podniesie - jeśli chcesz powtórzyć iterację, potrzebujesz nowego.Wracając do dykt
Widzieliśmy powtarzające się dyktaty w wielu kontekstach. Zauważyliśmy, że za każdym razem, gdy powtarzamy dyktando, dostajemy klucze. Powrót do oryginalnego przykładu:
Jeśli zmienimy nazwę zmiennej, nadal otrzymamy klucze. Spróbujmy:
Jeśli chcemy iterować po wartościach, musimy zastosować
.values
metodę dyktowania lub dla obu razem.items
:W podanym przykładzie bardziej efektywne byłoby iterowanie takich elementów:
Ale dla celów akademickich przykład tego pytania jest w porządku.
źródło
Mam przypadek użycia, w którym muszę iterować po słowie, aby uzyskać klucz, parę wartości, a także indeks wskazujący, gdzie jestem. Tak to robię:
Zauważ, że nawiasy wokół klucza, wartość jest ważna, bez nawiasów otrzymasz błąd ValueError „za mało wartości do rozpakowania”.
źródło
Możesz sprawdzić implementację CPython
dicttype
na GitHub. To jest podpis metody, która implementuje iterator dict:CPython dictobject.c
źródło
Aby iterować po klawiszach, jest wolniejszy, ale lepiej go używać
my_dict.keys()
. Jeśli próbowałeś zrobić coś takiego:spowodowałoby to błąd w czasie wykonywania, ponieważ zmieniasz klucze podczas działania programu. Jeśli absolutnie zależy Ci na skróceniu czasu, skorzystaj z
for key in my_dict
drogi, ale zostałeś ostrzeżony;).źródło
Spowoduje to wydrukowanie wyniku w porządku posortowanym według wartości w porządku rosnącym.
Wynik:
źródło