2013-07-24 22 views
7

Ich versuche, ein Verständnis zu schreiben, die zwei Wörterbücher in der folgenden Art und Weise komponieren:Python: Begreifen zwei Wörterbücher zu komponieren

d1 = {1:'a',2:'b',3:'c'} 
d2 = {'a':'A','b':'B','c':'C'} 
result = {1:'A',2:'B',3:'C'} 

Das heißt, das resultierende Wörterbuch von den Tasten des ersten gebildet wird und die Werte des zweiten für jedes Paar, wobei der Wert des ersten gleich dem Schlüssel des zweiten ist. Diese

ist das, was ich bisher habe:

{ k1:v2 for (k1,v1) in d1 for (k2,v2) in d2 if v1 == k2 } 

, aber es funktioniert nicht. Ich bin neu bei Python, also bin ich mir nicht sicher, ob das wirklich Sinn macht. Ich benutze Python 3.3.2 übrigens.

Vielen Dank im Voraus.

+0

Dank an alle, ich wünschte, ich könnte mehr als einen akzeptieren. – Roma149

Antwort

9

Eine Möglichkeit, es zu tun ist:

result = {k: d2.get(v) for k, v in d1.items()} 

Welches Verhalten für Schlüssel wollten Sie, die einen Wert haben, der nicht in d2 ist?

+0

+1 für nicht abstürzen, wenn 'd2' keinen Schlüssel für einen Wert in' d1' hat. –

+0

Funktioniert wie ein Charme, vielen Dank. Ich habe einen festen Satz von Eingängen, von denen ich weiß, dass sie das Format haben, also ist es in Ordnung, wenn ich dieses Verhalten nicht spezifiziere. – Roma149

+1

Nur um explizit zu sein - das obige gibt jedem nicht übereinstimmenden Schlüssel den Wert 'None'. Um nicht übereinstimmende Schlüssel wegzulassen, würden Sie '{k: d2 [v] für k, v in d1.items() wenn v in d2}' –

6

Gerade Schleife durch die Elemente von d1 und dann für jedes Element, das Sie in dem Ergebnis setzen wollen nicht den Wert von d1 verwenden, sondern stattdessen den neuen Wert innerhalb d2d1 ‚mit nachschlagen s Wert als Schlüssel:

>>> d1 = {1: 'a', 2: 'b', 3: 'c'} 
>>> d2 = {'a': 'A', 'b': 'B', 'c': 'C'} 
>>> d = {k: d2[v] for (k, v) in d1.items()} 
>>> d 
{1: 'A', 2: 'B', 3: 'C'} 
2

auf diese Weise funktioniert auch, wenn nicht alle Werte in d1 sind gültige Schlüssel für d2:

{k1:d2[d1[k1]] for k1 in d1 if d1[k1] in d2} 
2
This is what I've got so far: 

    { k1:v2 for (k1,v1) in d1 for (k2,v2) in d2 if v1 == k2 } 

Zwei Dinge sollten Sie beachten:

1) Wenn Sie eine for-in-Schleife verwenden, um direkt auf einem dict:

for (k1, v1) in some_dict: 

Python Schleifen über die Tasten im dict, das heißt, dass für-in-Schleife äquivalent zu:

for (k1, v1) in some_dict.keys() 

Aber Sie python sagen, dass es eine zwei Tupel jedes Mal sein wird, durch die Schleife zurück, (k1, v1) zurückgibt, und python nur jedes Mal durch die Schleife Taste. Das ist also ein Fehler. Sie können, dass durch Schreiben korrigieren:

for (k1, v1) in some_dict.items() 

Die Positionen() Funktion gibt einen zwei Tupel: (Schlüssel, Wert) jedes Mal durch die Schlaufe.

2) Angenommen, haben Sie diese Daten:

data = [ 
    [1, 2, 3], 
    ['a', 'b', 'c'] 
] 

Schleife über jedes der sechs Werte, es fühlt sich natürlich zu schreiben:

results = [x for x in inner_array for inner_array in data] 

Aber das erzeugt den Fehler:

Traceback (most recent call last): 
    File "1.py", line 5, in <module> 
    results = [x for x in inner_array for inner_array in data] 
NameError: name 'inner_array' is not defined 

Damit es funktioniert, müssen die Schleifen "rückwärts" geschrieben werden:

results = [x for inner_array in data for x in inner_array] 
print results 

--output:-- 
[1, 2, 3, 'a', 'b', 'c'] 

Ich denke, der einfachste Weg, das zu erinnern ist: die Schleifen in der gleichen Reihenfolge wie wenn man sie ohne eine Liste Verständnis schrieb:

results = [] 

for inner_array in data: 
    for x in inner_array: 
     results.append(x) 

Ich persönlich würde gerne sehen geändert in Python, so dass innerhalb einer Liste/dict/set Verständnis Sie arbeiten "von innen nach außen", wie Sie es geschrieben haben. In jedem Fall sieht Ihr Code mit den Änderungen so aus:

d1 = {1:'a',2:'b',3:'c'} 
d2 = {'a':'A','b':'B','c':'C'} 

results = { 
     k1: v2 
     for (k2,v2) in d2.items() 
     for (k1,v1) in d1.items() if v1 == k2 
} 

print results 

--output:-- 
{1: 'A', 2: 'B', 3: 'C'} 
+0

@ Roma149 verwenden. Es könnte hilfreich sein, meine Erklärung zu lesen, was Sie getan haben falsch, wenn du dein Diktatverständnis schreibst. – 7stud

+0

Wow, hervorragende Erklärung, ich schätze es wirklich. Es scheint, dass meine Version immerhin Sinn ergab :) – Roma149

+0

@ Roma149, Yep. Du hattest es fast. Verdammt gut für einen Anfänger. – 7stud

Verwandte Themen