6 Stimmen

Gibt es einen besseren Weg, um eine Liste in ein Wörterbuch in Python mit Schlüsseln, aber keine Werte zu konvertieren?

Ich war mir sicher, dass es einen One-Liner geben würde, um eine Liste in ein Wörterbuch zu konvertieren, wobei die Elemente in der Liste Schlüssel sind und das Wörterbuch keine Werte hat.

Die einzige Möglichkeit, die ich finden konnte, war, dagegen zu argumentieren.

"Die Verwendung von Listenauffassungen, wenn das Ergebnis ignoriert wird, ist irreführend und ineffizient. A for Schleife ist besser"

myList = ['a','b','c','d']
myDict = {}
x=[myDict.update({item:None}) for item in myList]

>>> myDict
{'a': None, 'c': None, 'b': None, 'd': None}

Es funktioniert, aber gibt es einen besseren Weg, dies zu tun?

23voto

Ayman Hourieh Punkte 122012

Verwenden Sie dict.fromkeys :

>>> my_list = [1, 2, 3]
>>> dict.fromkeys(my_list)
{1: None, 2: None, 3: None}

Die Standardwerte sind None aber Sie können sie als optionales Argument angeben:

>>> my_list = [1, 2, 3]
>>> dict.fromkeys(my_list, 0)
{1: 0, 2: 0, 3: 0}

Aus den Unterlagen:

a.fromkeys(seq[, value]) Erzeugt ein neues Wörterbuch mit Schlüsseln aus seq und Werte auf Wert gesetzt.

dict.fromkeys ist eine Klassenmethode, die ein neues Wörterbuch zurückgibt. value ist standardmäßig None. Neu in Version 2.3.

15voto

Greg Hewgill Punkte 882617

Sie könnten eine einstellen. anstelle eines Diktats:

>>> myList=['a','b','c','d']
>>> set(myList)
set(['a', 'c', 'b', 'd'])

Dies ist besser, wenn Sie nie Werte speichern müssen und nur eine ungeordnete Sammlung von eindeutigen Elementen speichern wollen.

5voto

Alex Martelli Punkte 805329

Um die Leistungssorgen des Fragestellers zu beantworten (für Suchvorgänge in dict gegen set ), etwas überraschend, dict Nachschlagen kann nur geringfügig schneller sein (in Python 2.5.1 auf meinem recht langsamen Laptop), wenn man beispielsweise annimmt, dass die Hälfte der Suchvorgänge fehlschlägt und die Hälfte erfolgreich ist. Hier ist, wie man über herauszufinden geht:

$ python -mtimeit -s'k=dict.fromkeys(range(99))' '5 in k and 112 in k'
1000000 loops, best of 3: 0.236 usec per loop
$ python -mtimeit -s'k=set(range(99))' '5 in k and 112 in k'
1000000 loops, best of 3: 0.265 usec per loop

jede Prüfung mehrmals durchführen, um zu überprüfen, ob sie wiederholbar ist. Wenn also diese 30 Nanosekunden oder weniger auf einem langsamen Laptop ein absolut entscheidender Engpass sind, kann es sich lohnen, sich für die obskuren dict.fromkeys Lösung als die einfache, offensichtliche, lesbare und eindeutig richtige set (ungewöhnlich - in Python hat die einfache und direkte Lösung fast immer auch Leistungsvorteile).

Natürlich muss man dies mit der eigenen Python-Version, der eigenen Maschine, den eigenen Daten und dem Verhältnis von erfolgreichen zu fehlgeschlagenen Tests überprüfen, et bestätigen, dass die Einsparung von 30 Nanosekunden (oder was auch immer) bei dieser Suche einen großen Unterschied ausmacht, wenn das Profil extrem genau erstellt wird.

Glücklicherweise wird sich dies in den allermeisten Fällen als völlig unnötig erweisen... aber da Programmierer wird sich mit sinnlosen Mikro-Optimierungen beschäftigen trotzdem Egal, wie oft man ihnen sagt, dass sie irrelevant sind, die timeit Modul ist in der Standardbibliothek enthalten, um diese meist bedeutungslosen Mikro-Benchmarks kinderleicht zu machen;-)

1voto

Mark Rushakoff Punkte 236626

Und hier ist ein ziemlich falscher und ineffizienter Weg, dies mit der Karte zu tun:

>>> d = dict()
>>> map (lambda x: d.__setitem__(x, None), [1,2,3])
[None, None, None]
>>> d
{1: None, 2: None, 3: None}

1voto

RexE Punkte 16299

Sie können ein Listenverständnis verwenden:

my_list = ['a','b','c','d']
my_dict = dict([(ele, None) for ele in my_list])

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X