2013-01-24 16 views
289

Ist es möglich, ein Wörterbuch Verständnis in Python (für die Schlüssel) zu erstellen?Python Wörterbuch Verständnis

Ohne Listenkomprehensionen, können Sie so etwas wie folgt verwenden:

l = [] 
for n in range(1, 11): 
    l.append(n) 

Wir dies zu einer Liste Verständnis verkürzen können: l = [n for n in range(1, 11)].

Allerdings sage ich, dass ich die Schlüssel eines Wörterbuchs auf den gleichen Wert festlegen möchte. ich tun kann:

d = {} 
for n in range(1, 11): 
    d[n] = True # same value for each 

Ich habe dies versucht:

d = {} 
d[i for i in range(1, 11)] = True 

Allerdings habe ich eine SyntaxError auf dem for bekommen.

Zusätzlich (ich diesen Teil nicht brauchen, aber nur fragen), können Sie ein Wörterbuch der Schlüssel zu einer Reihe von verschiedenen Werte eingestellt, wie folgt aus:

d = {} 
for n in range(1, 11): 
    d[n] = n 

mit einem Wörterbuch Verständnis dies möglich ist ?

d = {} 
d[i for i in range(1, 11)] = [x for x in range(1, 11)] 

Dies wirft auch ein SyntaxError auf dem for.

+1

Für zukünftige Leser Info: NumPy Arrays können Sie mehrere Elemente auf einen einzelnen Wert oder eine Liste von Werten festlegen, wie Sie es versuchen. Wenn Sie jedoch keinen Grund haben, NumPy zu verwenden, lohnt es sich wahrscheinlich nicht, nur für diese Funktion. –

Antwort

390

Es gibt , aber sie funktionieren nicht ganz so, wie Sie es versuchen. Wie ein Listenverständnis erstellen sie ein neues Wörterbuch; Sie können sie nicht verwenden, um einem vorhandenen Wörterbuch Schlüssel hinzuzufügen. Außerdem müssen Sie die Schlüssel und Werte angeben, obwohl Sie natürlich auch einen Dummy-Wert angeben können.

>>> d = {n: n**2 for n in range(5)} 
>>> print d 
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16} 

Wenn Sie wollen, dass sie alle auf True gesetzt:

>>> d = {n: True for n in range(5)} 
>>> print d 
{0: True, 1: True, 2: True, 3: True, 4: True} 

Was Sie scheinen zu fragen ist, ist ein Weg, um mehrere Tasten auf einmal auf einem vorhandenen Wörterbuch einzustellen. Es gibt keine direkte Abkürzung dafür. Sie können entweder eine Schleife verwenden, wie Sie bereits gezeigt haben, oder Sie können ein Wörterbuchverständnis verwenden, um ein neues dict mit den neuen Werten zu erstellen, und dann eingeben, um die neuen Werte in das alte dict einzufügen.

+10

FWIW, 'dict.update' kann auch iterierbare Schlüssel/Wert-Paare akzeptieren, genau wie der 'dict'-Konstruktor – mgilson

+1

Beachten Sie, dass Sie' dict.fromkeys() 'verwenden, wenn Sie ein Dictionary mit allen Werten erstellen möchten. Um alle Werte auf 'True' zu ​​setzen, verwenden Sie' dict.fromkeys (range (5), True) '. Pass auf, der Wert ist * nicht kopiert *, also solltest du dies vermeiden, wenn du einen veränderbaren Wert hast; Es wird zwischen allen Schlüsseln geteilt. –

+1

Hinweis: Die Schlüssel können auch das Ergebnis einer Methode sein: '{n * 2: n für n im Bereich (3)} => {0: 0, 2: 1, 4: 2}'. Beides kann im selben Ausdruck erfolgen: '{n * 2: n * 3 für n im Bereich (3)} => {0: 0, 2: 3, 4: 6}'. – Zaaier

136

Sie können die dict.fromkeys Klassenmethode verwenden ...

>>> dict.fromkeys(range(1, 11), True) 
{1: True, 2: True, 3: True, 4: True, 5: True, 6: True, 7: True, 8: True, 9: True, 10: True} 

Dies ist der schnellste Weg, um ein Wörterbuch, in dem alle Schlüssel auf den gleichen Wert Karte zu erstellen.

Seien Sie vorsichtig mit diesem mit veränderbaren Objekten aber:

d = dict.fromkeys(range(10), []) 
d[1].append(2) 
print(d[2]) # ??? 

Wenn Sie nicht wirklich Notwendigkeit, um alle Tasten zu initialisieren, ein defaultdict könnte auch nützlich sein:

from collections import defaultdict 
d = defaultdict(lambda: True) 

Um den zweiten Teil zu beantworten, ist ein dict-Verständnis genau das, was Sie brauchen:

Oder für python2.6:

dict((k, k) for k in range(10)) 

Sie könnten auch eine geschickte Unterklasse von dict schaffen, die ein wenig wie ein defaultdict funktioniert, wenn Sie __missing__ außer Kraft setzen:

>>> class KeyDict(dict): 
... def __missing__(self, key): 
...  #self[key] = key # Maybe add this also??? 
...  return key 
... 
>>> d = KeyDict() 
>>> d[1] 
1 
>>> d[2] 
2 
>>> d[3] 
3 
>>> print(d) 
{} 

Ordentlich.

+0

Beachten Sie, dass im Fall von 'd = defaultdict (Lambda: True)' das Lambda nicht erforderlich ist, da True änderbar ist (oder nicht). – rhbvkleef

21
>>> {i:i for i in range(1, 11)} 
{1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10} 
10

Verwenden dict() auf einer Liste von Tupeln, diese Lösung ermöglicht es Ihnen, beliebige Werte in jeder Liste zu haben, solange sie die gleiche Länge

i_s = range(1, 11) 
x_s = range(1, 11) 
# x_s = range(11, 1, -1) # Also works 
d = dict([(i_s[index], x_s[index],) for index in range(len(i_s))]) 
+10

Als eine Randnotiz, das ist das gleiche wie 'd = dict (zip (i_s, x_s))' – mgilson

-2

sind, können Sie nicht hash eine Liste wie diese. versuchen, dies stattdessen verwendet es Tupel

d[tuple([i for i in range(1,11)])] = True 
+6

Dies ist überhaupt nicht was das OP wollte ... –

6

Der Hauptzweck einer Liste Verständnis ist eine neue Liste auf einer anderen Basis zu schaffen, ohne Änderung oder die ursprüngliche Liste zu zerstören.

Statt zu schreiben

l = [] 
    for n in range(1, 11): 
     l.append(n) 

oder

l = [n for n in range(1, 11)] 

sollten Sie schreiben nur

l = range(1, 11) 

In den beiden Top-Codeblöcke Sie eine neue Liste erstellen, durchlaufen und jedes Element einfach zurückgeben. Es ist nur eine teure Art, eine Listenkopie zu erstellen.

Um ein neues Wörterbuch mit allen Tasten auf den gleichen Wert auf einem anderen dict Basis gesetzt zu bekommen, dies tun:

old_dict = {'a': 1, 'c': 3, 'b': 2} 
    new_dict = { key:'your value here' for key in old_dict.keys()} 

Sie eine Syntax empfangen, weil, wenn Sie

d = {} 
    d[i for i in range(1, 11)] = True 

Sie schreiben Ich sage grundsätzlich: "Setze meinen Schlüssel 'i für i in Bereich (1, 11)' auf 'True' und 'i für i in Bereich (1, 11)" ist kein gültiger Schlüssel, es ist nur ein Syntaxfehler. Wenn dicts Listen als Schlüssel unterstützt, würden Sie so etwas wie

d[[i for i in range(1, 11)]] = True 

und nicht

d[i for i in range(1, 11)] = True 

aber Listen sind nicht hashable tun, so dass man sich nicht als dict Schlüssel verwenden kann.

16

Ich mag den @mgilson-Kommentar wirklich, denn wenn Sie zwei iterables haben, einen, der den Schlüsseln und den anderen den Werten entspricht, können Sie auch Folgendes tun.

keys = ['a', 'b', 'c'] 
values = [1, 2, 3] 
d = dict(zip(keys, values)) 

geben

d = { 'a': 1, 'b': 2 'c': 3}

9

Betrachten dieses Beispiel für das Auftreten von Wörtern Zählen in einer Liste mit Wörterbuch Verständnis

my_list = ['hello', 'hi', 'hello', 'today', 'morning', 'again', 'hello'] 
my_dict = {k:my_list.count(k) for k in my_list} 
print(my_dict) 

Und das Ergebnis ist

{'again': 1, 'hi': 1, 'hello': 3, 'today': 1, 'morning': 1} 
+0

Dies ist interessant, obwohl nicht die effizienteste wie Sie Tasten wie "Hallo" mehrmals zählen werden – FuriousGeorge

Verwandte Themen