2013-12-11 3 views
5

Caveat: Dies ist eine gerade nach oben Frage für Code-Golf spielen, so dass ich weiß, was ich ist eine schlechte Praxis in der Produktion zu fragenÄndern einer Liste während einer Liste Verständnis mit anhängen

Ich versuche zu ändern ein Array während eines Listenverständnisses, aber aus irgendeinem Grund hängt es und ich weiß nicht warum oder wie ich das beheben kann.

Ich habe es mit einer Liste von Listen von unbestimmter Tiefe zu tun und muss sie zu einer flachen Liste zusammenfassen - for those curious its this question. Aber an dieser Stelle, sagen wir einfach, brauche ich eine flache Liste aller Elemente in der Liste, und 0, wenn es eine Liste ist.

Die normale Methode ist durch die Liste zu durchlaufen und wenn sie eine Liste, um es am Ende hinzufügen, etwa so:

for o in x: 
if type(o)==type([]):x+=o 
else:i+=o 
print i 

Ich versuche, dies mit Liste Verständnis zu verkürzen, wie so.

print sum([ 
[o,x.append(o) or 0][type(o)==type([])] 
for o in x 
])) 

Nun, ich List.append kehrt Keine wissen, um so sicherzustellen, dass ich einen numerischen Wert, faul Auswertung erhalten sagt, ich x.append(o) or 0 tun können, und da None „falsy“ ist, wird es den zweiten Teil evaulate und der Wert ist 0.

Aber es tut es nicht. Wenn ich x.append() in das Listenverständnis über x setze, bricht es nicht ab, oder es tritt ein Fehler auf, oder es wird ein Iterationsfehler zurückgegeben. Warum friert append während des Listenverständnisses ein, aber die obige Schleife for funktioniert einwandfrei?

bearbeiten: Um diese Frage zu halten von gelöscht werden, ich bin für den Golfsport Tipps nicht suchen (sie aber sehr lehrreich sind), ich war auf der Suche nach einer Antwort auf die Frage, warum der Code nicht, wie ich arbeiten hatte es geschrieben.

+0

Off-Topic für diese Frage, aber für das ursprüngliche Problem: Wäre es nicht einfacher, die verschachtelten iterable in einen Iterator (die Sie in einer 2-Zeilen-Funktion in 3.3 +, eine 3-Zeilen-Funktion tun können) Ohne, wenn Sie keine Module von Drittanbietern wie 'more-itertools' verwenden können, schreiben Sie einfach den trivialen Code über diesen Iterator? – abarnert

+0

@abarnert 'von itertools import *' ist 22 Zeichen lang, dann müssen Sie die tatsächliche Methode aufrufen. Das ist ein ziemlich hoher Preis für eine Bibliothek. –

+0

'Summe (Karte (Lambda x: x% 2-.5, flat (a)))' ist nur 37 Zeichen. 22 + 1 + 37 = 60, was sicherlich die 73, die es jetzt gibt, schlägt. – abarnert

Antwort

8

or kann faul sein, aber Listendefinitionen sind nicht. Für jede o in x, wenn die [o,x.append(o) or 0][type(o)==type([])] Ungeheuerlichkeit ausgewertet wird, hat Python [o,x.append(o) or 0] zu bewerten, was bedeutet, x.append(o) or 0 Auswertung, was bedeutet, dass o-x angehängt wird, unabhängig davon, ob es sich um eine Liste. So erhalten Sie mit jedem Element von x-x hängten, und dann werden sie angehängt wieder und wieder und wieder und OutOfMemoryError

+0

Ich habe nicht lange genug gewartet, um den Fehler zu sehen Reißbrett denke ich :( –

+1

@LegoStormtroopr: Wenn Sie auf 6 sind 4-bit Python, auf einer Plattform, die den Swap nach Bedarf erweitert (wie OS X und Windows standardmäßig tun), kann der Fehler erst nach stundenlangem Swap-Thrashing auftreten ... – abarnert

3

Was:

y = [element for element in x if type(element) != list or x.extend(element)] 

(beachten Sie, dass extend abflachen, während append wird Fügen Sie die verschachtelte Liste nur bis zum Ende zurück, nicht geglättet).

+2

Warum nicht einfach 'type (element)! = List '? 'list' * ist * der Typ von' [] '. – mgilson

+0

Ahem, richtig! Ich änderte @ Lego Code und wurde mit dem Wind getragen :) Danke! Korrigiert! – Roberto

+0

Brillantes Golf, aber es beantwortet nicht wirklich die Frage. Allerdings konnte ich nicht in gutem Bewusstsein dies als meine eigene Lösung der Herausforderung unterstellen und vorschlagen, dass Sie stattdessen tun. –