Verwendung der Python-Notation für Listenauflösungen

Geschäft

In Python ist es einfach, bei der Erstellung einer neuen Liste die Notation für Listenauflösungen zu verwenden.(List comprehensions)

In diesem Artikel werden wir zunächst Folgendes besprechen

  • Grundtyp der Notation für das Listenverständnis
  • Notation des Listenverständnisses mit bedingter Verzweigung durch if
  • Kombination mit ternären Operatoren (if else-ähnliche Verarbeitung)
  • zip(),enumerate()Kombination mit diesen
  • Notation der verschachtelten Listeneinbindung

Als Nächstes werden wir die Notation des Listenverständnisses anhand von Beispielcode erläutern.

  • Mengeneinschlussnotation(Set comprehensions)
  • Wörterbucheintragsschreibweise(Dict comprehensions)
  • Generatortyp(Generator expressions)

Grundtyp der Notation für das Listenverständnis

Die Notation für das Listenverständnis wird wie folgt geschrieben.

[Expression for Any Variable Name in Iterable Object]

Es nimmt jedes Element eines iterierbaren Objekts wie eine Liste, ein Tupel oder einen Bereich mit einem beliebigen Variablennamen und wertet es mit einem Ausdruck aus. Es wird eine neue Liste mit dem Ergebnis der Auswertung als Element zurückgegeben.

Ein Beispiel wird zusammen mit einer entsprechenden for-Anweisung gegeben.

squares = [i**2 for i in range(5)]
print(squares)
# [0, 1, 4, 9, 16]
squares = []
for i in range(5):
    squares.append(i**2)

print(squares)
# [0, 1, 4, 9, 16]

Der gleiche Prozess kann mit map() durchgeführt werden, aber die Notation für das Listenverständnis wird wegen ihrer Einfachheit und Klarheit bevorzugt.

Notation des Listenverständnisses mit bedingter Verzweigung durch if

Eine bedingte Verzweigung mit if ist ebenfalls möglich. Schreiben Sie das if im Postfix wie folgt.

[Expression for Any Variable Name in Iterable Object if Conditional Expression]

Nur die Elemente des iterierbaren Objekts, deren bedingter Ausdruck wahr ist, werden durch den Ausdruck ausgewertet, und eine neue Liste, deren Elemente das Ergebnis sind, wird zurückgegeben.

Sie können jeden beliebigen Variablennamen in dem bedingten Ausdruck verwenden.

Ein Beispiel wird zusammen mit einer entsprechenden for-Anweisung gegeben.

odds = [i for i in range(10) if i % 2 == 1]
print(odds)
# [1, 3, 5, 7, 9]
odds = []
for i in range(10):
    if i % 2 == 1:
        odds.append(i)

print(odds)
# [1, 3, 5, 7, 9]

Der gleiche Prozess kann mit filter() durchgeführt werden, aber die Notation für das Listenverständnis wird wegen ihrer Einfachheit und Klarheit bevorzugt.

Kombination mit ternären Operatoren (if else-ähnliche Verarbeitung)

Im obigen Beispiel werden nur die Elemente verarbeitet, die die Kriterien erfüllen, und die Elemente, die die Kriterien nicht erfüllen, werden aus der neuen Liste ausgeschlossen.

Wenn Sie den Prozess in Abhängigkeit von der Bedingung umschalten wollen oder wenn Sie Elemente, die die Bedingung nicht erfüllen, anders verarbeiten wollen, wie in if else, verwenden Sie den ternären Operator.

In Python kann der ternäre Operator wie folgt geschrieben werden

Value When True if Conditional Expression else Value When False

Dies wird im Ausdrucksteil der Notation für das Listenverständnis wie unten gezeigt verwendet.

[Value When True if Conditional Expression else Value When False for Any Variable Name in Iterable Object]

Ein Beispiel wird zusammen mit einer entsprechenden for-Anweisung gegeben.

odd_even = ['odd' if i % 2 == 1 else 'even' for i in range(10)]
print(odd_even)
# ['even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd']
odd_even = []
for i in range(10):
    if i % 2 == 1:
        odd_even.append('odd')
    else:
        odd_even.append('even')

print(odd_even)
# ['even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd']

Es ist auch möglich, Ausdrücke zu schreiben, die beliebige Variablennamen für die wahren und falschen Werte verwenden.

Wenn die Bedingung erfüllt ist, wird etwas verarbeitet, andernfalls wird der Wert des ursprünglichen iterierbaren Objekts unverändert gelassen.

odd10 = [i * 10 if i % 2 == 1 else i for i in range(10)]
print(odd10)
# [0, 10, 2, 30, 4, 50, 6, 70, 8, 90]

Kombination mit zip() und enumerate()

Nützliche Funktionen, die oft in der for-Anweisung verwendet werden, sind z.B. zip(), das mehrere Iterables kombiniert, und enumerate(), das einen Wert zusammen mit seinem Index zurückgibt.

Natürlich ist es möglich, zip() und enumerate() mit der Notation des Listenverständnisses zu verwenden. Es handelt sich dabei nicht um eine spezielle Syntax, und es ist nicht schwierig, wenn man die Korrespondenz mit der for-Anweisung berücksichtigt.

Beispiel für zip().

l_str1 = ['a', 'b', 'c']
l_str2 = ['x', 'y', 'z']

l_zip = [(s1, s2) for s1, s2 in zip(l_str1, l_str2)]
print(l_zip)
# [('a', 'x'), ('b', 'y'), ('c', 'z')]
l_zip = []
for s1, s2 in zip(l_str1, l_str2):
    l_zip.append((s1, s2))

print(l_zip)
# [('a', 'x'), ('b', 'y'), ('c', 'z')]

Beispiel für enumerate().

l_enu = [(i, s) for i, s in enumerate(l_str1)]
print(l_enu)
# [(0, 'a'), (1, 'b'), (2, 'c')]
l_enu = []
for i, s in enumerate(l_str1):
    l_enu.append((i, s))

print(l_enu)
# [(0, 'a'), (1, 'b'), (2, 'c')]

Die Idee ist die gleiche wie bei der Verwendung von if.

l_zip_if = [(s1, s2) for s1, s2 in zip(l_str1, l_str2) if s1 != 'b']
print(l_zip_if)
# [('a', 'x'), ('c', 'z')]

Jedes Element kann auch zur Berechnung eines neuen Elements verwendet werden.

l_int1 = [1, 2, 3]
l_int2 = [10, 20, 30]

l_sub = [i2 - i1 for i1, i2 in zip(l_int1, l_int2)]
print(l_sub)
# [9, 18, 27]

Notation der verschachtelten Listeneinbindung

Wie bei der Verschachtelung von for-Schleifen kann auch die Notation für das Listenverständnis verschachtelt werden.

[Expression for Variable Name 1 in Iterable Object 1
    for Variable Name 2 in Iterable Object 2
        for Variable Name 3 in Iterable Object 3 ... ]

Der Einfachheit halber wurden Zeilenumbrüche und Einrückungen eingefügt, die jedoch für die Grammatik nicht erforderlich sind; sie können in einer einzigen Zeile fortgesetzt werden.

Ein Beispiel wird zusammen mit einer entsprechenden for-Anweisung gegeben.

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

flat = [x for row in matrix for x in row]
print(flat)
# [1, 2, 3, 4, 5, 6, 7, 8, 9]
flat = []
for row in matrix:
    for x in row:
        flat.append(x)

print(flat)
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

Es ist auch möglich, mehrere Variablen zu verwenden.

cells = [(row, col) for row in range(3) for col in range(2)]
print(cells)
# [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1)]

Sie können auch bedingte Verzweigungen durchführen.

cells = [(row, col) for row in range(3)
         for col in range(2) if col == row]
print(cells)
# [(0, 0), (1, 1)]

Es ist auch möglich, für jedes iterierbare Objekt bedingt zu verzweigen.

cells = [(row, col) for row in range(3) if row % 2 == 0
         for col in range(2) if col % 2 == 0]
print(cells)
# [(0, 0), (2, 0)]

Mengeneinschlussnotation(Set comprehensions)

Wenn man die eckigen Klammern [] in der Notation für das Listenverständnis durch geschweifte Klammern {} ersetzt, wird eine Menge (ein Objekt vom Typ “Menge”) erzeugt.

{Expression for Any Variable Name in Iterable Object}
s = {i**2 for i in range(5)}

print(s)
# {0, 1, 4, 9, 16}

Wörterbucheintragsschreibweise(Dict comprehensions)

Wörterbücher (Objekte vom Typ dict) können auch mit der comprehension-Notation erzeugt werden.

{}, und geben Sie den Schlüssel und den Wert im Ausdrucksteil als Schlüssel: Wert an.

{Key: Value for Any Variable Name in Iterable Object}

Für Schlüssel und Wert kann ein beliebiger Ausdruck angegeben werden.

l = ['Alice', 'Bob', 'Charlie']

d = {s: len(s) for s in l}
print(d)
# {'Alice': 5, 'Bob': 3, 'Charlie': 7}

Um ein neues Wörterbuch aus einer Liste von Schlüsseln und Werten zu erstellen, verwenden Sie die Funktion zip().

keys = ['k1', 'k2', 'k3']
values = [1, 2, 3]

d = {k: v for k, v in zip(keys, values)}
print(d)
# {'k1': 1, 'k2': 2, 'k3': 3}

Generatortyp(Generator expressions)

Wenn eckige Klammern [] in der Notation der Listenauffassungen als runde Klammern () verwendet werden, wird ein Generator anstelle eines Tupels zurückgegeben. Dies wird als Generatorausdrücke bezeichnet.

Beispiel für die Notation des Listenverständnisses.

l = [i**2 for i in range(5)]

print(l)
# [0, 1, 4, 9, 16]

print(type(l))
# <class 'list'>

Beispiel für einen Generator-Ausdruck. Wenn Sie den Generator mit print() ausdrucken, wird sein Inhalt nicht ausgegeben, aber wenn Sie ihn mit einer for-Anweisung ausführen, können Sie den Inhalt erhalten.

g = (i**2 for i in range(5))

print(g)
# <generator object <genexpr> at 0x10af944f8>

print(type(g))
# <class 'generator'>

for i in g:
    print(i)
# 0
# 1
# 4
# 9
# 16

Generatorausdrücke erlauben auch bedingte Verzweigungen und Verschachtelungen unter Verwendung der if- sowie der Listenauffassungsnotation.

g_cells = ((row, col) for row in range(0, 3)
           for col in range(0, 2) if col == row)

print(type(g_cells))
# <class 'generator'>

for i in g_cells:
    print(i)
# (0, 0)
# (1, 1)

Wird beispielsweise eine Liste mit einer großen Anzahl von Elementen mit Hilfe der Listenauffassungsnotation erstellt und dann mit einer for-Anweisung in einer Schleife durchlaufen, wird die Liste mit allen Elementen am Anfang erstellt, wenn die Listenauffassungsnotation verwendet wird. Wenn Sie dagegen einen Generator-Ausdruck verwenden, werden die Elemente bei jeder Wiederholung der Schleife einzeln erzeugt, wodurch der Speicherbedarf verringert wird.

Wenn der Generatorausdruck das einzige Argument der Funktion ist, können die runden Klammern () weggelassen werden.

print(sum([i**2 for i in range(5)]))
# 30

print(sum((i**2 for i in range(5))))
# 30

print(sum(i**2 for i in range(5)))
# 30

Was die Verarbeitungsgeschwindigkeit anbelangt, so ist die Listenverstehensschreibweise oft schneller als die Generatorschreibweise, wenn alle Elemente verarbeitet werden.

Bei der Beurteilung mit all() oder any() beispielsweise wird das Ergebnis jedoch bestimmt, wenn false oder true vorhanden ist, so dass die Verwendung von Generatorausdrücken schneller sein kann als die Verwendung der Notation für das Listenverständnis.

Es gibt keine Tupelverstehensnotation, aber wenn Sie einen Generatorausdruck als Argument von tuple() verwenden, können Sie ein Tupel in der Verstehensnotation erzeugen.

t = tuple(i**2 for i in range(5))

print(t)
# (0, 1, 4, 9, 16)

print(type(t))
# <class 'tuple'>
Copied title and URL