Wie kann ich List Comprehensions verwenden, um eine verschachtelte Liste zu verarbeiten?

Lesezeit: 11 Minuten

Benutzeravatar von Boy Pasmo
Junge Pasmo

Ich habe diese verschachtelte Liste:

l = [['40', '20', '10', '30'], ['20', '20', '20', '20', '20', '30', '20'], ['30', '20', '30', '50', '10', '30', '20', '20', '20'], ['100', '100'], ['100', '100', '100', '100', '100'], ['100', '100', '100', '100']]

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.

    – 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 von x vom vorherigen Code übrig geblieben.

    – Karl Knechtel

    2. August 2022 um 21:43 Uhr

Benutzeravatar von Andrew Clark
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.

Benutzeravatar von Rahul
Raul

So konvertieren Sie eine verschachtelte for-Schleife in ein verschachteltes Listenverständnis:

Geben Sie hier die Bildbeschreibung ein

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)]

    – WestCoastProjects

    5. März 2021 um 15:36 Uhr

>>> l = [['40', '20', '10', '30'], ['20', '20', '20', '20', '20', '30', '20'], ['30', '20', '30', '50', '10', '30', '20', '20', '20'], ['100', '100'], ['100', '100', '100', '100', '100'], ['100', '100', '100', '100']]
>>> new_list = [float(x) for xs in l for x in xs]
>>> new_list
[40.0, 20.0, 10.0, 30.0, 20.0, 20.0, 20.0, 20.0, 20.0, 30.0, 20.0, 30.0, 20.0, 30.0, 50.0, 10.0, 30.0, 20.0, 20.0, 20.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0]

Benutzeravatar von Aaditya Ura
Aaditya Ura

Ich wollte mitteilen, wie das Listenverständnis tatsächlich funktioniert, insbesondere für verschachtelte Listenverständnisse:

new_list= [float(x) for x in l]

ist eigentlich dasselbe wie:

new_list=[]
for x in l:
    new_list.append(float(x))

Und nun zum Verständnis der verschachtelten Liste:

[[float(y) for y in x] for x in l]

ist das gleiche wie:

new_list=[]
for x in l:
    sub_list=[]
    for y in x:
        sub_list.append(float(y))

    new_list.append(sub_list)

print(new_list)

Ausgang:

[[40.0, 20.0, 10.0, 30.0], [20.0, 20.0, 20.0, 20.0, 20.0, 30.0, 20.0], [30.0, 20.0, 30.0, 50.0, 10.0, 30.0, 20.0, 20.0, 20.0], [100.0, 100.0], [100.0, 100.0, 100.0, 100.0, 100.0], [100.0, 100.0, 100.0, 100.0]]

Benutzeravatar von Sohaib Farooqi
Sohaib Farooqi

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

Geben Sie hier die Bildbeschreibung ein

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

Geben Sie hier die Bildbeschreibung ein

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

Geben Sie hier die Bildbeschreibung ein

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.

Benutzeravatar von Remi Guan
Remi Guan

Wenn Sie keine verschachtelten Listenverständnisse mögen, können Sie die verwenden Karte funktionieren auch,

>>> from pprint import pprint

>>> l = l = [['40', '20', '10', '30'], ['20', '20', '20', '20', '20', '30', '20'], ['30', '20', '30', '50', '10', '30', '20', '20', '20'], ['100', '100'], ['100', '100', '100', '100', '100'], ['100', '100', '100', '100']] 

>>> pprint(l)
[['40', '20', '10', '30'],
['20', '20', '20', '20', '20', '30', '20'],
['30', '20', '30', '50', '10', '30', '20', '20', '20'],
['100', '100'],
['100', '100', '100', '100', '100'],
['100', '100', '100', '100']]

>>> float_l = [map(float, nested_list) for nested_list in l]

>>> pprint(float_l)
[[40.0, 20.0, 10.0, 30.0],
[20.0, 20.0, 20.0, 20.0, 20.0, 30.0, 20.0],
[30.0, 20.0, 30.0, 50.0, 10.0, 30.0, 20.0, 20.0, 20.0],
[100.0, 100.0],
[100.0, 100.0, 100.0, 100.0, 100.0],
[100.0, 100.0, 100.0, 100.0]]

  • 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


1443380cookie-checkWie kann ich List Comprehensions verwenden, um eine verschachtelte Liste zu verarbeiten?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy