2016-06-27 13 views
1

Ich versuche grundsätzlich, mit einem Listenverständnis mit diesem elementaren Code-Code herumzukommen. Im Versuch, ein Listenelement durch den Wert des Listenelementes zu duplizieren:Listenelemente mehrfach mit Listenverständnis vervielfältigen

y = [1, 2, 0, 1] 
x = [] 
for i in y: 
    for j in range(i): 
     x.append(i) 
# Desired output 
>>> [1, 2, 2, 1] 

x = [i for _ in range(i) for i in y] 
# Wrong output 
>>> [1, 2, 0, 1] 

# Right output 
x = [j for j in y for _ in range(j)] 
>>> [1, 2, 2, 1] 

Ich kann nicht scheinen, um meinen Kopf zu umgehen, warum ich den falschen Ausgang für das zweite Beispiel erhalten. Könnte jemand erklären, was hier falsch ist. Vielen Dank.

+0

Ihr erstes Verständnis '[i für _ in Bereich (i) für i in y]' gibt einen Fehler bei der Ausführung (Nämlich, Name 'i' ist nicht definiert '). In verschachtelten Listenkompromittierungen gehen Schleifen von außen nach innen. – Rahul

+1

@Rahul Es würde diesen Fehler nicht auslösen, da die 'for'-Schleife in den vorherigen Zeilen den Wert von 'i' verlieren wird. – Selcuk

+1

Siehe auch http://StackOverflow.com/a/17657966/4014959 –

Antwort

3

Wenn Sie mehrere for Schleifen innerhalb eines Listenverständnisses haben, l Oops werden in der gleichen Reihenfolge verarbeitet, in der sie "traditionelle" for Loops verwenden. Ihre Liste comp, die die richtige Ausgabe gibt, hat die Schleifen in der gleichen Reihenfolge wie der Code am Anfang mit .append mit traditionellen for Schleifen.

Wie Rahul erwähnt in den Kommentaren, in Isolation,

x = [i for _ in range(i) for i in y] 

würde eine

NameError: name 'i' is not defined 

Es tut in diesem Fall nicht, weil i durch den früheren Code definiert wurde.


Im Gegensatz dazu sehen, was passiert mit einer verschachtelten Liste comp:

y = [1, 2, 0, 1] 
x = [[j for j in range(i)] for i in y] 
print(x)  

Ausgang

[[0], [0, 1], [], [0]] 

Hier ist die äußerste Schleife im äußeren Verständnis ist und die Innen Schleife ist im inneren Verständnis. Also erstellen wir für jede Iteration der for i in y eine neue Listenkomp. Und in dieser Liste comp schleifen wir über range(i).

1

Das richtige Verständnis ist:

x = [i for i in y for j in range(i)] 

Diese gibt das gewünschte Ergebnis
Artikel für Artikel in der Liste Bereich (Artikel) mal
diese thread

flattened = [val for sublist in list_of_lists for val in sublist] 
inspiriert
-1
x = [j for j in y for i in range(j)] 
+1

Dieser Code ist ein wenig verwirrend, weil er 'y' wiederverwendet. Außerdem ist es immer besser, SO eine Erklärung für den Code hinzuzufügen. Code-only-Antworten ohne Erklärung sind von begrenztem Nutzen. –

+0

Danke @PM 2Ring, Code korrigiert –