Bagaimana cara menginisialisasi dict dengan kunci dari daftar dan nilai kosong di Python?

251

Saya ingin dapatkan dari ini:

keys = [1,2,3]

untuk ini:

{1: None, 2: None, 3: None}

Apakah ada cara pythonic untuk melakukannya?

Ini adalah cara jelek untuk melakukannya:

>>> keys = [1,2,3]
>>> dict([(1,2)])
{1: 2}
>>> dict(zip(keys, [None]*len(keys)))
{1: None, 2: None, 3: None}
Juanjo Conti
sumber

Jawaban:

390

dict.fromkeys([1, 2, 3, 4])

Ini sebenarnya adalah metode kelas, jadi ini berfungsi untuk dict-subclass (seperti collections.defaultdict) juga. Argumen opsional kedua menentukan nilai yang akan digunakan untuk kunci (default ke None.)

Thomas Wouters
sumber
154
Berhati-hatilah dengan menginisialisasi ke sesuatu yang bisa berubah: Jika Anda memanggil, mis. dict.fromkeys([1, 2, 3], []), Semua tombol dipetakan ke daftar yang sama, dan memodifikasi satu akan memodifikasi semuanya.
charleslparker
8
Inisialisasi dengan {k:[] for k in [1, 2, 3]}masih aman.
Aziz Alto
263

tidak ada yang peduli untuk memberikan solusi pemahaman dict?

>>> keys = [1,2,3,5,6,7]
>>> {key: None for key in keys}
{1: None, 2: None, 3: None, 5: None, 6: None, 7: None}
Adrien Plisson
sumber
32
Saya percaya itu di-backport ke 2,7
wim
21
Ini bagus dan tidak mengalami masalah dengan referensi yang diterima oleh jawaban yang diterima.
charleslparker
Ini juga memungkinkan Anda untuk menetapkan nilai default (misalnya False).
neverendingqs
Ini adalah cara Pythonic terbersih dan terbanyak dalam Python3 IMO
Bede Constantinides
4
Menggunakan dict-comp juga memungkinkan nilai menjadi hasil dari memanggil fungsi (yang dapat diberikan kunci sebagai argumen, jika diinginkan) - demikian juga mekanisme yang sangat kuat.
martineau
56
dict.fromkeys(keys, None)
Dominic Cooney
sumber
2
luar biasa, saya ingin daftar kosong,dict.fromkeys(keys, [])
muon
12
@ muon Itu hampir pasti bukan yang Anda inginkan, lihat komentar charleslparker .
gerrit
Bekerja dalam Python versi 2.6.6.
Mike Finch
2
Hati-hati: ini akan menginisialisasi dict dengan semua poin kunci dengan nilai tunggal yang sama
Mendi Barel
16
>>> keyDict = {"a","b","c","d"}

>>> dict([(key, []) for key in keyDict])

Keluaran:

{'a': [], 'c': [], 'b': [], 'd': []}
Mayur Koshti
sumber
1
Sementara kode ini dapat menjawab pertanyaan, memberikan konteks tambahan tentang bagaimana dan / atau mengapa memecahkan masalah akan meningkatkan nilai jangka panjang jawaban.
Francesco Menzani
4
namanya keyDictmenyesatkan, karena baris pertama kode mengembalikan a set, bukan a dict.
Bryan Oakley
10
d = {}
for i in keys:
    d[i] = None
inspectorG4dget
sumber
1
Mengapa Python membuang kesalahan seperti TypeError: 'type' object is not iterable:?
FaCoffee
1
@FrancescoCastellani Karena listadalah tipe. Kecuali Anda memiliki sesuatu seperti list = [], metode di atas akan selalu memberi Anda kesalahan yang sama
smac89
1

Di banyak alur kerja di mana Anda ingin melampirkan nilai default / awal untuk kunci sewenang-wenang, Anda tidak perlu hash masing-masing tombol secara terpisah sebelumnya. Anda bisa menggunakannya collections.defaultdict. Sebagai contoh:

from collections import defaultdict

d = defaultdict(lambda: None)

print(d[1])  # None
print(d[2])  # None
print(d[3])  # None

Ini lebih efisien, menghemat hash semua kunci Anda di instantiation. Selain itu, defaultdictadalah subkelas dari dict, jadi biasanya tidak perlu mengkonversi kembali ke kamus biasa.

Untuk alur kerja di mana Anda memerlukan kontrol pada kunci yang diizinkan, Anda dapat menggunakan dict.fromkeyssesuai jawaban yang diterima:

d = dict.fromkeys([1, 2, 3, 4])
jpp
sumber