'For' döngülerini kullanarak sözlükler üzerinde yineleme


3138

Aşağıdaki kod tarafından biraz şaşkınım:

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

Anlamadığım keykısım. Python, yalnızca anahtarın sözlükten okunması gerektiğini nasıl anlar? Mı keyPython özel bir kelime? Yoksa basitçe bir değişken mi?


3
Yeni bir yanıt göndermeden önce, bu soru için zaten 10'dan fazla yanıt olduğunu düşünün. Lütfen yanıtınızın mevcut yanıtlar arasında yer almayan bilgilere katkıda bulunduğundan emin olun.
janniks

Yanıtlar:


5392

key sadece değişken bir isimdir.

for key in d:

basitçe, anahtarlar ve değerler yerine sözlükteki anahtarlar arasında geçiş yapar. Hem anahtar hem de değer üzerinde döngü yapmak için aşağıdakileri kullanabilirsiniz:

Python 3.x için:

for key, value in d.items():

Python 2.x için:

for key, value in d.iteritems():

Kendiniz test etmek için kelimeyi keyolarak değiştirin poop.

Python 3.x'te, iteritems()basitçe değiştirildi items(), bu da dict tarafından desteklenen set benzeri bir görünüm döndürdü, iteritems()ancak daha da iyi. Bu aynı zamanda 2.7 olarak da mevcuttur viewitems().

İşlem items()hem 2 hem de 3 için çalışacak, ancak 2'de sözlüğün (key, value)çiftlerinin bir listesini döndürecek ve items()çağrıdan sonra gerçekleşen dikte değişikliklerini yansıtmayacaktır . 3.x 'de 2.x davranışı istiyorsanız, çağırabilirsiniz list(d.items()).


158
Böyle bir değere erişmemek için gözden kaçan bir neden eklemek: for döngüsünün içindeki d [anahtar], anahtarın yeniden özetlenmesine neden olur (değeri almak için). Sözlük büyük olduğunda, bu ekstra sağlama toplam süreye eklenir. Bu Raymond Hettinger'in teknik konuşmasında tartışılmıştır youtube.com/watch?v=anrOzOapJ2E
quiet_penguin

27
Öğelerin öngörülemez bir sırada yineleneceğini ve sortedstabilize edilmesi için gerekli olduğunu belirtmek mantıklı olabilir.
yugr

5
@HarisankarKrishnaSwamy alternatif nedir?
JoeyC

3
@yugr Bunu neden söyledin? Dokümanlar diyor Keys and values are iterated over in insertion order. [ docs.python.org/3/library/…
Geza Turi

4
@yugr Python 3.7'den, sözlükler ekleme siparişine sahiptir ve bu bir dil özelliğidir. Bkz. Stackoverflow.com/a/39980744/9428564
Aimery

433

Bu anahtar özel bir sözcük değildir, ancak sözlükler yineleyici protokolünü uygular. Bunu sınıfınızda yapabilirsiniz, örneğin sınıf yineleyicilerini nasıl oluşturacağınız için bu soruya bakın .

Sözlükler söz konusu olduğunda, C düzeyinde uygulanır. Ayrıntılar PEP 234'te mevcuttur . Özellikle, "Sözlük Yineleyicileri" başlıklı bölüm:

  • Sözlükler, sözlüğün anahtarları üzerinden yinelenen verimli bir yineleyici döndüren bir tp_iter yuvası uygular. [...] Bu, yazabileceğimiz anlamına gelir

    for k in dict: ...

    ki buna eşit, ancak çok daha hızlı

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

    sözlükte yapılan değişiklikler (döngü veya başka bir iş parçacığı tarafından) kısıtlanmadığı sürece ihlal edilmez.

  • Farklı yineleyici türlerini açıkça döndüren sözlüklere yöntemler ekleyin:

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

    Bu for x in dictkestirme anlamına gelir for x in dict.iterkeys().

Python 3, dict.iterkeys(), dict.itervalues()ve dict.iteritems()artık desteklenmektedir. Kullanım dict.keys(), dict.values()ve dict.items()bunun yerine.


207

dictGördüğünüz gibi, yinelemeleri anahtarları aracılığıyla belirli bir sırayla yineleme :

Düzenleme: (Bu artık Python3.6'da geçerli değildir , ancak henüz garanti edilmediğini unutmayın )

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

Örneğin, kullanmak daha iyi bir fikirdir dict.items():

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

Bu size bir tuples listesi verir. Bunları böyle döndürdüğünüzde, her bir demet paketten çıkarılır kve votomatik olarak:

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

Döngü gövdesi yalnızca birkaç satırsa, a üzerinde döngü yaparken kve vdeğişken adları olarak kullanmak dictoldukça yaygındır. Daha karmaşık döngüler için daha açıklayıcı adlar kullanmak iyi bir fikir olabilir:

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

Biçim dizelerini kullanma alışkanlığına sahip olmak iyi bir fikirdir:

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

11
Python 3.7 sürüm notlarından: "Dikte edilen nesnelerin ekleme emri koruma doğası artık Python dil spesifikasyonunun resmi bir parçasıdır."
Gregory Arenius

86

key basitçe bir değişkendir.

İçin Python2.X :

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

... ya da daha iyisi,

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

İçin Python3.X :

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

63

for .. in ..-Syntax kullanarak sözlükler arasında yineleme yaptığınızda, her zaman tuşların üzerinde yinelenir (değerlere kullanarak erişilebilir dictionary[key]).

Anahtar / değer çiftlerini yinelemek için Python 2'de for k,v in s.iteritems()ve Python 3'te kullanın for k,v in s.items().


38
Python 3 items()yerine , bunun yerineiteritems()
Andreas Fester


19

'For' döngülerini kullanarak sözlükler üzerinde yineleme

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

Python, yalnızca anahtarın sözlükten okunması gerektiğini nasıl anlar? Anahtar Python'da özel bir kelime midir? Yoksa basitçe bir değişken mi?

Sadece fordöngüler değil . Buradaki önemli kelime "yineleme" dir.

Sözlük, anahtarların değerlerle eşleştirilmesidir:

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

Ne zaman yinelersek, anahtarlar üzerinden yineliyoruz. Değişken adının keysadece açıklayıcı olması amaçlanmıştır ve bu amaç için oldukça uygundur.

Bu bir liste kavrayışında olur:

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

Sözlüğü listeye (veya başka bir koleksiyon türü nesnesine) ilettiğimizde olur:

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

Python'un yineleme şekli, ihtiyaç duyduğu bir bağlamda, __iter__bir yineleyici (bu durumda bir keyiterator nesnesi) döndüren nesnenin yöntemini (bu durumda sözlük) çağırır:

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

Bu özel yöntemleri kendimiz kullanmamalıyız, bunun yerine ilgili yerleşik işlevi kullanmak için şunu kullanmalıyız iter:

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

Yineleyicilerin bir __next__yöntemi vardır - ancak bunu yerleşik işlevle adlandırırız 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

Bir yineleyici bittiğinde yükselir StopIteration. Python bir fordöngüden, bir liste kavramasından, bir üreteç ifadesinden veya başka bir yinelemeli bağlamdan çıkmayı bilmektedir . Bir yineleyici yükseldiğinde StopIterationher zaman yükseltir - tekrarlamak isterseniz, yeni bir tane gerekir.

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

Dikte etmek

Birçok bağlamda yinelemelerin yinelendiğini gördük. Gördüğümüz şey, bir dikte üzerinde her yinelediğimizde, anahtarları elde etmemizdir. Orijinal örneğe geri dön:

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

Değişken adını değiştirirsek, yine de anahtarları alırız. Hadi deneyelim:

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

Değerler üzerinde yineleme yapmak istiyorsak .values, dikte yöntemini veya her ikisi için birlikte kullanmamız gerekir .items:

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

Verilen örnekte, aşağıdaki gibi öğeler üzerinde yineleme yapmak daha verimli olacaktır:

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

Ancak akademik amaçlar için, sorunun örneği gayet iyi.


17

Ben anahtar, değer çifti, aynı zamanda nerede olduğumu gösteren dizin almak için dikte yinelemek zorunda bir kullanım durum var. Bunu nasıl yaparım:

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

Anahtar, değer etrafındaki parantezlerin önemli olduğunu unutmayın, parantez olmadan "açmak için yeterli değer yok" değeri alırsınız.


1
Bu soru ile ne kadar ilgili?
jorijnsmit

8

CPython'ların uygulamasını dicttypeGitHub'da kontrol edebilirsiniz . Dikte yineleyicisini uygulayan yöntemin imzası budur:

_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey,
             PyObject **pvalue, Py_hash_t *phash)

CPython dictobject.c


4

Anahtarları yinelemek için daha yavaş ama kullanımı daha iyidir my_dict.keys(). Böyle bir şey yapmaya çalıştıysanız:

for key in my_dict:
    my_dict[key+"-1"] = my_dict[key]-1

program çalışırken tuşları değiştirdiğiniz için bir çalışma zamanı hatası oluşturur. Kesinlikle zaman azaltmaya ayarlıysanız, for key in my_dictyolu kullanın , ancak uyarıldı;).


2

Bu, çıktıyı Değerlere göre Sıralı düzende artan sırada yazdırır.

d = {'x': 3, 'y': 1, 'z': 2}
def by_value(item):
    return item[1]

for key, value in sorted(d.items(), key=by_value):
    print(key, '->', value)

Çıktı:

resim açıklamasını buraya girin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.