Mengapa Anda harus memanggil .items () saat mengulangi kamus menggunakan Python?

131

Mengapa Anda harus menelepon items()untuk beralih lebih dari kunci, pasangan nilai dalam kamus? yaitu.

dic = {'one': '1', 'two': '2'}
for k, v in dic.items():
    print(k, v)

Mengapa itu bukan perilaku standar pengulangan pada kamus

for k, v in dic:
    print(k, v)
Falmarri
sumber

Jawaban:

171

Untuk setiap wadah python C, harapannya adalah itu

for item in C:
    assert item in C

akan lulus dengan baik - tidakkah Anda akan merasa heran jika satu pengertian in(klausa loop) memiliki makna yang sama sekali berbeda dari yang lain (pemeriksaan keberadaan)? Saya yakin akan! Secara alami berfungsi seperti itu untuk daftar, set, tuple, ...

Jadi, kapan Ckamus, jika inmenghasilkan kunci / nilai tupel dalam satu forlingkaran, maka, dengan prinsip paling tidak heran, injuga harus mengambil tuple seperti operan kirinya di cek kontainmen.

Seberapa bermanfaatkah itu? Cukup berguna memang, pada dasarnya membuat if (key, value) in Csinonim untuk if C.get(key) == value- yang merupakan cek saya percaya saya mungkin telah melakukan, atau ingin melakukan, 100 kali lebih jarang dari apa yang if k in Csebenarnya berarti , memeriksa keberadaan kunci saja dan sepenuhnya mengabaikan nilai.

Di sisi lain, keinginan untuk mengulang hanya pada tombol cukup umum, misalnya:

for k in thedict:
    thedict[k] += 1

memiliki nilai juga tidak akan membantu khususnya:

for k, v in thedict.items():
    thedict[k] = v + 1

sebenarnya agak kurang jelas dan kurang ringkas. (Perhatikan bahwa itemsitu adalah ejaan asli dari metode "tepat" yang digunakan untuk mendapatkan pasangan kunci / nilai: sayangnya itu kembali pada hari-hari ketika para pengakses tersebut mengembalikan seluruh daftar, sehingga untuk mendukung "hanya mengulangi" ejaan alternatif harus diperkenalkan , dan iteritems itu - di Python 3, di mana kendala kompatibilitas ke belakang dengan versi Python sebelumnya jauh lebih lemah, itu menjadi itemslagi).

Alex Martelli
sumber
10

Dugaan saya: Menggunakan tupel penuh akan lebih intuitif untuk pengulangan, tetapi mungkin kurang untuk pengujian untuk menggunakan keanggotaan in.

if key in counts:
    counts[key] += 1
else:
    counts[key] = 1

Kode itu tidak akan berfungsi jika Anda harus menentukan kunci dan nilainya in. Saya mengalami kesulitan membayangkan use case di mana Anda akan memeriksa apakah kedua kunci DAN nilai ada di kamus. Jauh lebih alami untuk hanya menguji kunci.

# When would you ever write a condition like this?
if (key, value) in dict:

Sekarang tidak perlu bahwa inoperator dan for ... inberoperasi pada item yang sama. Dari segi implementasi, keduanya adalah operasi yang berbeda ( __contains__vs. __iter__). Tetapi ketidakkonsistenan kecil itu akan agak membingungkan dan, yah, tidak konsisten.

John Kugelman
sumber
Mengingat bahwa untuk setiap jenis builtin iterable yang dapat saya pikirkan, x in foohanya jika idalam for i in foomengasumsikan nilai xpada titik tertentu, saya akan mengatakan bahwa itu akan menjadi inkonsistensi yang sangat besar .
aaronasterling