foo = [x for x in bar if x.occupants > 1]
Nachdem ich hier gegoogelt und gesucht hatte, konnte ich nicht herausfinden, was dies bewirkt. Vielleicht habe ich nicht das richtige Zeug gesucht, aber hier ist es. Jede Eingabe zum Entlarven dieser Kurzschrift wird sehr geschätzt.
python
for-loop
for-in-loop
Greg Flynn
quelle
quelle
python "* for * in * if"
und dies war der erste Treffer secnetix.de/olli/Python/list_comprehensions.hawkAntworten:
Die aktuellen Antworten sind gut, aber sprechen Sie nicht darüber, wie sie nur syntaktischer Zucker für ein Muster sind, an das wir so gewöhnt sind.
Beginnen wir mit einem Beispiel, sagen wir, wir haben 10 Zahlen, und wir wollen eine Teilmenge von denen, die größer als beispielsweise 5 sind.
>>> numbers = [12, 34, 1, 4, 4, 67, 37, 9, 0, 81]
Für die obige Aufgabe sind die folgenden Ansätze völlig identisch und gehen von ausführlich bis prägnant, lesbar und pythonisch :
Ansatz 1
result = [] for index in range(len(numbers)): if numbers[index] > 5: result.append(numbers[index]) print result #Prints [12, 34, 67, 37, 9, 81]
Ansatz 2 (etwas sauberere For-In-Schleifen)
result = [] for number in numbers: if number > 5: result.append(number) print result #Prints [12, 34, 67, 37, 9, 81]
Ansatz 3 (Listenverständnis eingeben)
result = [number for number in numbers if number > 5]
oder allgemeiner:
[function(number) for number in numbers if condition(number)]
wo:
function(x)
ein nimmtx
und verwandelt es in etwas Nützliches (wie zum Beispiel:x*x
)condition(x)
ein False-y-Wert zurückgegeben wird (False, None, leere Zeichenfolge, leere Liste usw.), wird die aktuelle Iteration übersprungen (thinkcontinue
). Wenn die Funktion einen Nicht-False-y-Wert zurückgibt, gelangt der aktuelle Wert zum endgültigen resultierenden Array (und durchläuft den obigen Transformationsschritt).Um die Syntax etwas anders zu verstehen, lesen Sie den Abschnitt Bonus unten.
Weitere Informationen finden Sie im Tutorial, das alle anderen Antworten verlinkt haben: Listenverständnis
Bonus
(Etwas unpythonisch, aber der Vollständigkeit halber hier)
Das obige Beispiel kann wie folgt geschrieben werden:
result = filter(lambda x: x > 5, numbers)
Der obige allgemeine Ausdruck kann wie folgt geschrieben werden:
result = map(function, filter(condition, numbers)) #result is a list in Py2
quelle
x*x
, ist es oft nur da und nichtsquare(x)
. Es macht es noch schmerzhafter dann , wenn ich diesen Ausdruck sehe in ein Lambda - Dosen, zB[x**2 for x in range(5)]
gegenübermap(lambda x: x**2, range(5))
.Es ist ein Listenverständnis
foo
wird eine gefilterte Listebar
der Objekte mit dem Attribut Insassen> 1 seinbar
kann einlist
,set
,dict
oder jede andere iterableHier ist ein Beispiel zur Verdeutlichung
>>> class Bar(object): ... def __init__(self, occupants): ... self.occupants = occupants ... >>> bar=[Bar(0), Bar(1), Bar(2), Bar(3)] >>> foo = [x for x in bar if x.occupants > 1] >>> foo [<__main__.Bar object at 0xb748516c>, <__main__.Bar object at 0xb748518c>]
Foo hat also 2
Bar
Objekte, aber wie überprüfen wir, welche es sind? Fügen wir eine__repr__
Methode hinzu,Bar
damit sie informativer ist>>> Bar.__repr__=lambda self:"Bar(occupants={0})".format(self.occupants) >>> foo [Bar(occupants=2), Bar(occupants=3)]
quelle
Soweit ich das beurteilen kann, sollte dies so funktionieren, dass überprüft wird, ob die Liste "bar" leer ist (0) oder aus einem Singleton (1) über x.occupants besteht, wobei x ein definiertes Element in der Listenleiste ist und kann die Eigenschaft von Insassen haben. Also wird foo aufgerufen, geht die Liste durch und gibt dann alle Elemente zurück, die die Prüfbedingung x.occupant bestehen.
In einer Sprache wie Java würden Sie eine Klasse namens "x" erstellen, in der 'x'-Objekte dann einem Array oder ähnlichem zugewiesen werden. X hätte ein Feld namens "Insassen" und jeder Index würde mit der Methode x.occupants überprüft, die die Nummer zurückgibt, die dem Insassen zugewiesen ist. Wenn diese Methode größer als 1 zurückgibt (wir nehmen an, dass ein int hier als Teilbelegung ungerade wäre), würde die foo-Methode (die auf dem fraglichen Array oder ähnlich aufgerufen wird) ein Array oder ähnliches zurückgeben, wie in der foo-Methode definiert für dieses Container-Array oder was haben Sie. Die Elemente des zurückgegebenen Arrays wären die 'x'-Objekte im ersten Array-Ding, die den Kriterien von "Größer als 1" entsprechen.
Python verfügt über integrierte Methoden über das Listenverständnis, um dies viel prägnanter und erheblich vereinfacht zu handhaben. Anstatt zwei vollständige Klassen und mehrere Methoden zu implementieren, schreibe ich diese eine Codezeile.
quelle
Dies gibt eine Liste zurück, die alle Elemente in der Leiste enthält, deren Insassen> 1 sind.
quelle
Da der Programmierteil der Frage von anderen vollständig beantwortet wird, ist es schön, seine Beziehung zur Mathematik zu kennen ( Mengenlehre ). Eigentlich ist es die Python-Implementierung der Set Builder-Notation :
Um B mit Listenverständnis zu erstellen , werden die Mitglieder von B (bezeichnet mit x ) aus Satz A ausgewählt, wobei
S(x) == True
(Einschlussbedingung).Hinweis: Eine Funktion,
S
die einen Booleschen Wert zurückgibt, wird als Prädikat bezeichnet .quelle