Jak zainicjować dykt za pomocą kluczy z listy i pustej wartości w Pythonie?

251

Chciałbym z tego uzyskać:

keys = [1,2,3]

do tego:

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

Czy istnieje pythoniczny sposób na zrobienie tego?

To brzydki sposób:

>>> keys = [1,2,3]
>>> dict([(1,2)])
{1: 2}
>>> dict(zip(keys, [None]*len(keys)))
{1: None, 2: None, 3: None}
Juanjo Conti
źródło

Odpowiedzi:

388

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

W rzeczywistości jest to metoda klasowa, więc działa również dla podklas dict (podobnych collections.defaultdict). Opcjonalny drugi argument określa wartość, której należy użyć dla kluczy (domyślnie to None.)

Thomas Wouters
źródło
153
Zachowaj ostrożność przy inicjowaniu na coś zmiennego: jeśli na przykład zadzwonisz, dict.fromkeys([1, 2, 3], [])wszystkie klucze są mapowane na tę samą listę, a modyfikacja jednego spowoduje ich zmianę.
charleslparker
8
Inicjowanie za pomocą {k:[] for k in [1, 2, 3]}jest jednak nadal bezpieczne.
Aziz Alto
263

nikt nie chciał dać rozwiązania ze zrozumieniem dykta?

>>> 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
źródło
32
Wydaje mi się, że została przeniesiona do wersji 2.7
wim
21
Jest to miłe i nie cierpi na problem referencyjny, który ma zaakceptowana odpowiedź.
charleslparker
Pozwala to również przypisać wartość domyślną (np False.).
neverendingqs
Jest to najczystszy, najbardziej Pythoniczny sposób w Python3 IMO
Bede Constantinides,
4
Użycie dict-comp pozwala również, aby wartość była wynikiem wywołania funkcji (która może być przekazana jako argument, jeśli jest to pożądane) - podobnie jak bardzo potężny mechanizm.
martineau,
56
dict.fromkeys(keys, None)
Dominic Cooney
źródło
2
super, chciałem pustych list,dict.fromkeys(keys, [])
muon
12
@muon To prawie na pewno nie to, czego chcesz, zobacz komentarz charleslparker .
gerrit
Działa w Pythonie w wersji 2.6.6.
Mike Finch
2
Uwaga: zainicjuje to dyktowanie ze wszystkimi punktami klucza do tej samej wartości
Mendi Barel
16
>>> keyDict = {"a","b","c","d"}

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

Wynik:

{'a': [], 'c': [], 'b': [], 'd': []}
Mayur Koshti
źródło
1
Chociaż ten kod może odpowiedzieć na pytanie, zapewnienie dodatkowego kontekstu dotyczącego tego, jak i / lub dlaczego rozwiązuje problem, poprawiłoby długoterminową wartość odpowiedzi.
Francesco Menzani
4
nazwa keyDictwprowadza w błąd, ponieważ pierwszy wiersz kodu zwraca a set, a nie a dict.
Bryan Oakley
10
d = {}
for i in keys:
    d[i] = None
inspectorG4dget
źródło
1
Dlaczego Python zgłasza błąd typu TypeError: 'type' object is not iterable:?
FaCoffee,
1
@FrancescoCastellani Ponieważ listjest typem. Jeśli nie masz czegoś takiego list = [], powyższa metoda zawsze da ci ten sam błąd
smac89
1

W wielu przepływach pracy, w których chcesz dołączyć domyślną / początkową wartość dla dowolnych kluczy, nie musisz hashować każdego klucza indywidualnie przed czasem. Możesz użyć collections.defaultdict. Na przykład:

from collections import defaultdict

d = defaultdict(lambda: None)

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

Jest to bardziej wydajne, oszczędza konieczności hashowania wszystkich kluczy w momencie tworzenia. Co więcej, defaultdictjest podklasą dict, więc zwykle nie ma potrzeby konwertowania z powrotem na zwykły słownik.

W przypadku przepływów pracy, w których potrzebujesz kontroli dozwolonych kluczy, możesz użyć dict.fromkeyszgodnie z przyjętą odpowiedzią:

d = dict.fromkeys([1, 2, 3, 4])
jpp
źródło