2016-11-11 2 views
4

definiert ein Wörterbuch wie folgt aus (Liste eine Liste von ganzen Zahlen):Erstellen einer Liste von über einem Wörterbuch Iterieren

my_dictionary = {'list_name' : list, 'another_list_name': another_list} 

Jetzt will ich von iterieren diesem Wörterbuch eine neue Liste erstellen. Am Ende möchte ich es so aussehen:

my_list = [list_name_list_item1, list_name_list_item2, 
       list_name_list_item3, another_list_name_another_list_item1] 

Und so weiter.

Meine Frage ist also: Wie kann ich das realisieren?

Ich versuchte

for key in my_dictionary.keys(): 
    k = my_dictionary[key] 
    for value in my_dictionary.values(): 
     v = my_dictionary[value] 
     v = str(v) 
     my_list.append(k + '_' + v) 

Doch statt der gewünschten Ausgabe erhalte ich einen Typ Fehler (unhashable Typ: 'Liste') in Zeile 4 dieses Beispiels.

Antwort

5

Sie versuchen, ein Wörterbuch Element nach Wert zu erhalten, während Sie bereits Ihren Wert haben.

Tun Sie es in einer Zeile eine Liste Verständnis mit:

my_dictionary = {'list_name' : [1,4,5], 'another_list_name': [6,7,8]} 

my_list = [k+"_"+str(v) for k,lv in my_dictionary.items() for v in lv] 

print(my_list) 

Ergebnis:

['another_list_name_6', 'another_list_name_7', 'another_list_name_8', 'list_name_1', 'list_name_4', 'list_name_5'] 

Beachten Sie, dass die Reihenfolge, in Ihrem Wörterbuch, da nicht garantiert ist, ist die Reihenfolge der Liste nicht entweder. Man könnte die Reihenfolge beheben, indem die Einzelteile entsprechend Tasten Reihenfolge:

my_list = [k+"_"+str(v) for k,lv in sorted(my_dictionary.items()) for v in lv] 
+0

Vielen Dank für Ihre Hilfe! Ich bin ziemlich neu bei Python, also schätze ich deine Erklärung und Lösung! :) – Hisushi

0

Sie eine äußere Schleife über Tasten geschrieben haben, dann eine innere Schleife über Werte, und versucht, jeden Wert als einen Schlüssel zu verwenden, die ist, wo Das Programm ist fehlgeschlagen. Einfach den items Methode des Wörterbuch verwenden, anstatt über Schlüssel, Wert-Paare iterieren:

["{}_{}".format(k,v) for k,v in d.items()] 

Ups, gewünscht wird, das Format parsen fehlgeschlagen; wir sollten jeden Gegenstand in der inneren Liste produzieren. Keine Sorge ...

d={1:[1,2,3],2:[4,5,6]} 
list(itertools.chain(*(
     ["{}_{}".format(k,i) for i in l] 
     for (k,l) in d.items()))) 

Dies ist ein wenig komplexer. Wir nehmen Schlüssel-Wert-Paare erneut aus dem Wörterbuch, machen dann eine innere Schleife über die Liste, die der Wert war, und formatieren diese in Zeichenfolgen. Dies erzeugt innere Sequenzen, so dass wir es mit Hilfe von chain und * reduzieren und schließlich das Ergebnis als eine Liste speichern.

Bearbeiten: Es stellt sich heraus, Python 3.4.3 wird ziemlich verwirrt, wenn dies als Generatorausdrücke verschachtelt; Ich musste das innere in eine Liste umwandeln, oder es würde irgendeine Kombination von k und l ersetzen, bevor ich die Formatierung durchführe.

Nochmals bearbeiten: Als jemand in einer seit gelöschten Antwort veröffentlicht (was mich verwirrt), bin ich überkompliziert Dinge. Sie können in einer verketteten Verständnis des abgeflachten Verschachtelung tun:

["{}_{}".format(k,v) for k,l in d.items() for v in l] 

Diese Methode auch von Jean-François Fabre geschrieben wurde.

2

starten:

my_list = [] 
for key in my_dictionary: 
    for item in my_dictionary[key]: 
     my_list.append(str(key) + '_' + str(item)) 

Hoffnung, das hilft.

0

Ihr sofortiges Problem ist, dass dict().values() ein Generator ist, der die Werte aus dem Wörterbuch ergibt, nicht die Schlüssel. Wenn Sie also versuchen, eine Suche in Zeile 4 durchzuführen, schlägt es (wie in diesem Fall) fehl nicht als Schlüssel verwendet werden. In einem anderen Fall, sagen {1:2, 3:4}, würde es mit einem KeyError fehlschlagen, und {1:2, 2:1} würde keinen Fehler auslösen, aber wahrscheinlich verwirrendes Verhalten geben.

Was Ihre eigentliche Frage anbelangt, schreiben Listen keine Daten wie Wörterbücher zu Daten; Sie speichern einfach den Index.

def f() 
    a = 1 
    b = 2 
    c = 3 
    l = [a, b, c] 

    return l 

f() Aufruf wird [1, 2, 3] zurückkehren, mit jedem Konzept von a, b und c völlig verloren.

Wenn Sie wollen einfach die Listen in Ihrem Wörterbuch verketten, um eine Kopie des ersten zu machen, dann .extend() fordert es genügt:

my_list = my_dictionary['list_name'][:] 
my_list.extend(my_dictionary['another_list_name']) 

Wenn Sie schauen, um die Reihenfolge der Listen zu halten "Gegenstände, während sie immer noch namentlich auf sie verweisen, schauen in die OrderedDict class in collections.

+0

Es ist nicht so, dass Werte() ein Generator ist; es ist, dass Werte keine Schlüssel sind. In seinem Fall handelt es sich um Listen, die nicht hashbar sind und daher * keine Schlüssel sein können, so dass er statt eines Schlüsselfehlers einen Typfehler erhält. –

+0

Ich habe es schlecht formuliert; es sollte "ist" statt "zurück" sagen. –

0

Verwenden Listenkomprehensionen wie diese

d = {"test1":[1,2,3,],"test2":[4,5,6],"test3":[7,8,9]} 

new_list = [str(item[0])+'_'+str(v) for item in d.items() for v in item[1]] 

Ausgang:

new_list: 
['test1_1', 
'test1_2', 
'test1_3', 
'test3_7', 
'test3_8', 
'test3_9', 
'test2_4', 
'test2_5', 
'test2_6'] 
0

Lassen Sie uns unsere Daten initialisieren

In [1]: l0 = [1, 2, 3, 4] 

In [2]: l1 = [10, 20, 30, 40] 

In [3]: d = {'name0': l0, 'name1': l1} 

Beachten Sie, dass in meinem Beispiel unterscheidet sich von Ihnen, den Inhalt der Listen ist nicht Zeichenketten ... sind nicht Listen heterogene Container?

Das heißt, Sie können nicht einfach die Schlüssel und die Elemente der Liste verbinden, Sie sollten diese Werte besser auf Zeichenfolgen mit dem eingebauten str(...) übertragen.

Jetzt kommt die Lösung für Ihr Problem ... Ich benutze ein Listenverständnis mit zwei Schleifen, kommt die äußere Schleife zuerst und es ist auf die Elemente (dh Schlüssel-Wert-Paare) im Wörterbuch, das innere Schleife kommt an zweiter Stelle und es ist auf den Elementen in der entsprechenden Liste.

In [4]: res = ['_'.join((str(k), str(i))) for k, l in d.items() for i in l] 

In [5]: print(res) 
['name0_1', 'name0_2', 'name0_3', 'name0_4', 'name1_10', 'name1_20', 'name1_30', 'name1_40'] 

In [6]: 

In Ihrem Fall str(k)+'_'+str(i) Verwendung auch wäre schön, aber die aktuelle Idiom für Saiten mit einem festen 'text' ist die 'text'.join(...) Fügeverfahren. Beachten Sie, dass .join ein einzelnes Argument, ein iterables, und daher in der Liste Verständnis verwendet join((..., ...)) , um die Joinands in einem einzigen Argument sammeln.

+0

post scriptum - Wie andere in ihren Antworten gesagt haben, haben Sie KEINE GARANTIE über eine bestimmte Reihenfolge der in der äußeren Schleife abgerufenen 'k, l' -Elemente. – gboffi

Verwandte Themen