Ich möchte jedes Element in konvertieren l Zu float. Ich habe diesen Code:
newList = []
for x in l:
for y in x:
newList.append(float(y))
Wie kann ich das Problem stattdessen mit einem verschachtelten Listenverständnis lösen?
Siehe auch: Wie kann ich ein flaches Ergebnis aus einem Listenverständnis anstelle einer verschachtelten Liste erhalten?
Tust du Auch Möchten Sie Ihre Liste glätten?
– Greg Hewgill
6. August 2013 um 6:05 Uhr
@GregHewgill: OP hat nicht geantwortet, aber basierend auf der Antwort, die sie akzeptiert haben, scheinen sie die Verschachtelung so beibehalten zu wollen.
[float(y) for y in x for x in l]funktioniert nicht von selbst. Es funktioniert nur aufgrund der bestehenden Definition von x vom vorherigen Code übrig geblieben.
– Karl Knechtel
2. August 2022 um 21:43 Uhr
Andreas Clark
So würden Sie dies mit einem verschachtelten Listenverständnis tun:
[[float(y) for y in x] for x in l]
Dies würde Ihnen eine Liste von Listen geben, ähnlich der, mit der Sie begonnen haben, außer mit Floats anstelle von Strings.
Wenn Sie eine flache Liste wollen, dann würden Sie verwenden
[float(y) for x in l for y in x]
Beachten Sie die Schleifenreihenfolge – for x in l steht bei diesem an erster Stelle.
Raul
So konvertieren Sie eine verschachtelte for-Schleife in ein verschachteltes Listenverständnis:
So funktioniert das Verstehen verschachtelter Listen:
l a b c d e f
↓ ↓ ↓ ↓ ↓ ↓ ↓
In [1]: l = [ [ [ [ [ [ 1 ] ] ] ] ] ]
In [2]: for a in l:
...: for b in a:
...: for c in b:
...: for d in c:
...: for e in d:
...: for f in e:
...: print(float(f))
...:
1.0
In [3]: [float(f)
for a in l
...: for b in a
...: for c in b
...: for d in c
...: for e in d
...: for f in e]
Out[3]: [1.0]
Für Ihren Fall, wenn Sie eine flache Liste wünschen, wird es so aussehen.
In [4]: new_list = [float(y) for x in l for y in x]
Super nützlich! Macht deutlich, dass Schleifen (von oben nach unten) im Generator von links nach rechts angeordnet sind. Dies ist seit in nicht offensichtlich (f(x) for x in l) platziert die zweite Zeile des Äquivalents der for-Schleife auf der linken Seite.
– Benutzer48956
11. Januar 2018 um 18:11 Uhr
@ user48956 Ja, ich denke nicht, dass es sehr intuitiv ist, ein verschachteltes Listenverständnis als Einzeiler zu haben. Eine solche Verwendung wäre imo ein Antimuster
– Fehler
14. April 2021 um 23:19 Uhr
Sie sind sich nicht sicher, was Ihre gewünschte Ausgabe ist, aber wenn Sie das Listenverständnis verwenden, folgt die Reihenfolge der Reihenfolge der verschachtelten Schleifen, die Sie rückwärts haben. Also habe ich das, was ich denke, was du willst mit:
[float(y) for x in l for y in x]
Das Prinzip ist: Verwenden Sie die gleiche Reihenfolge, in der Sie es als verschachtelte for-Schleifen schreiben würden.
Dies sollte die Antwort sein, da wir das Iteratool manchmal nicht in eckige Klammern setzen möchten
– Verzinkung
19. April 2017 um 1:48 Uhr
Dies ist möglicherweise nicht die richtige Antwort, da eine nicht verschachtelte Liste ausgegeben wird, aber genau danach habe ich gesucht das Prinzip. Danke!
– Rodrigo E. Principe
29. September 2017 um 10:52 Uhr
Das ist nicht korrekt: sollte eine Klammer haben [float(y)]
Ich hatte ein ähnliches Problem zu lösen, also bin ich auf diese Frage gestoßen. Ich habe einen Leistungsvergleich der Antwort von Andrew Clark und Narayan durchgeführt, den ich gerne teilen möchte.
Der Hauptunterschied zwischen zwei Antworten besteht darin, wie sie über innere Listen iterieren. Einer von ihnen verwendet builtin Karte, während andere das Listenverständnis verwenden. Die Kartenfunktion hat einen leichten Leistungsvorteil gegenüber dem entsprechenden Listenverständnis, wenn sie keine Verwendung von Lambdas erfordert. Also im Zusammenhang mit dieser Frage map sollte etwas besser abschneiden als das Listenverständnis.
Lassen Sie uns einen Leistungsbenchmark machen, um zu sehen, ob es wirklich stimmt. Ich habe Python Version 3.5.0 verwendet, um all diese Tests durchzuführen. In der ersten Reihe von Tests möchte ich Elemente pro Liste beibehalten 10 und Anzahl der Listen variieren 10-100.000
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*10]"
>>> 100000 loops, best of 3: 15.2 usec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*10]"
>>> 10000 loops, best of 3: 19.6 usec per loop
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*100]"
>>> 100000 loops, best of 3: 15.2 usec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*100]"
>>> 10000 loops, best of 3: 19.6 usec per loop
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*1000]"
>>> 1000 loops, best of 3: 1.43 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*1000]"
>>> 100 loops, best of 3: 1.91 msec per loop
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*10000]"
>>> 100 loops, best of 3: 13.6 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*10000]"
>>> 10 loops, best of 3: 19.1 msec per loop
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*100000]"
>>> 10 loops, best of 3: 164 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*100000]"
>>> 10 loops, best of 3: 216 msec per loop
In den nächsten Tests möchte ich die Anzahl der Elemente pro Liste erhöhen 100.
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*10]"
>>> 10000 loops, best of 3: 110 usec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*10]"
>>> 10000 loops, best of 3: 151 usec per loop
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*100]"
>>> 1000 loops, best of 3: 1.11 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*100]"
>>> 1000 loops, best of 3: 1.5 msec per loop
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*1000]"
>>> 100 loops, best of 3: 11.2 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*1000]"
>>> 100 loops, best of 3: 16.7 msec per loop
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*10000]"
>>> 10 loops, best of 3: 134 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*10000]"
>>> 10 loops, best of 3: 171 msec per loop
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*100000]"
>>> 10 loops, best of 3: 1.32 sec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*100000]"
>>> 10 loops, best of 3: 1.7 sec per loop
Lassen Sie uns einen mutigen Schritt machen und die Anzahl der Elemente in Listen ändern 1000
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*10]"
>>> 1000 loops, best of 3: 800 usec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*10]"
>>> 1000 loops, best of 3: 1.16 msec per loop
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*100]"
>>> 100 loops, best of 3: 8.26 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*100]"
>>> 100 loops, best of 3: 11.7 msec per loop
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*1000]"
>>> 10 loops, best of 3: 83.8 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*1000]"
>>> 10 loops, best of 3: 118 msec per loop
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*10000]"
>>> 10 loops, best of 3: 868 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*10000]"
>>> 10 loops, best of 3: 1.23 sec per loop
>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*100000]"
>>> 10 loops, best of 3: 9.2 sec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*100000]"
>>> 10 loops, best of 3: 12.7 sec per loop
Aus diesen Tests können wir das schließen map hat in diesem Fall einen Leistungsvorteil gegenüber dem Listenverständnis. Dies gilt auch, wenn Sie versuchen, auf eine der beiden zu übertragen int oder str. Für eine kleine Anzahl von Listen mit weniger Elementen pro Liste ist der Unterschied vernachlässigbar. Für größere Listen mit mehr Elementen pro Liste könnte man gerne verwenden map anstelle des Listenverständnisses, hängt jedoch vollständig von den Anwendungsanforderungen ab.
Ich persönlich finde das Listenverständnis jedoch lesbarer und idiomatischer als map. Es ist ein De-facto-Standard in Python. Normalerweise sind die Leute kompetenter und bequemer (insbesondere Anfänger) in der Verwendung des Listenverständnisses als map.
Remi Guan
Wenn Sie keine verschachtelten Listenverständnisse mögen, können Sie die verwenden Karte funktionieren auch,
Ihr Code generiert Kartenobjekte anstelle von Listen: >>> float_l = [map(float, nested_list) for nested_list in l][[<map at 0x47be9b0>], [<map at 0x47be2e8>], [<map at 0x47be4a8>], [<map at 0x47beeb8>], [<map at 0x484b048>], [<map at 0x484b0b8>]] aber das Hinzufügen eines zusätzlichen Aufrufs zur Liste funktioniert wie erwartet: >>> float_l = [list(map(float, nested_list)) for nested_list in l]
– Pixelperfekt
17. März 2017 um 15:49 Uhr
@pixelperfect das liegt an der (falsch informiert ..) verändern in python3 um Generatoren aus dem Verständnis zurückzugeben.
– WestCoastProjects
4. März 2018 um 4:56 Uhr
14433800cookie-checkWie kann ich List Comprehensions verwenden, um eine verschachtelte Liste zu verarbeiten?yes
Tust du Auch Möchten Sie Ihre Liste glätten?
– Greg Hewgill
6. August 2013 um 6:05 Uhr
@GregHewgill: OP hat nicht geantwortet, aber basierend auf der Antwort, die sie akzeptiert haben, scheinen sie die Verschachtelung so beibehalten zu wollen.
– smci
2. Februar 2018 um 20:39 Uhr
Siehe auch: treyhunner.com/2015/12/python-list-comprehensions-now-in-color
– Karl Knechtel
18. Februar 2022 um 21:32 Uhr
[float(y) for y in x for x in l]
funktioniert nicht von selbst. Es funktioniert nur aufgrund der bestehenden Definition vonx
vom vorherigen Code übrig geblieben.– Karl Knechtel
2. August 2022 um 21:43 Uhr