Ich weiß, wie man sowohl for-Schleifen als auch if-Anweisungen in separaten Zeilen verwendet, wie zum Beispiel:
>>> a = [2,3,4,5,6,7,8,9,0]
... xyz = [0,12,4,6,242,7,9]
... for x in xyz:
... if x in a:
... print(x)
0,4,6,7,9
Und ich weiß, dass ich ein Listenverständnis verwenden kann, um diese zu kombinieren, wenn die Aussagen einfach sind, wie zum Beispiel:
print([x for x in xyz if x in a])
Was ich jedoch nicht finden kann, ist ein gutes Beispiel (zum Kopieren und Lernen), das einen komplexen Satz von Befehlen (nicht nur "print x") zeigt, die nach einer Kombination aus einer for-Schleife und einigen if-Anweisungen auftreten. Etwas, das ich erwarten würde, sieht aus wie:
for x in xyz if x not in a:
print(x...)
Ist das nicht die Art und Weise, wie Python funktionieren soll?
python
loops
if-statement
for-loop
ChewyChunks
quelle
quelle
for
Schleife undif
Aussage zu vermeiden .x in a
Ist zum Beispiel langsam, wenna
es sich um eine Liste handelt.Antworten:
Sie können Generatorausdrücke wie folgt verwenden:
quelle
gen = (y for (x,y) in enumerate(xyz) if x not in a)
Gibt >>> zurück,12
wenn ich tippefor x in gen: print x
- warum also das unerwartete Verhalten bei der Aufzählung?for x in xyz if x:
for x in (x for x in xyz if x not in a):
funktioniert für mich, aber warum Sie nicht einfach dazu in der Lage sein solltenfor x in xyz if x not in a:
, bin ich mir nicht sicher ...Wie pro The Zen of Python (wenn Sie sich fragen , ob Ihr Code „Pythonic“, das ist der Ort zu gehen):
Der pythonische Weg, das von zwei s zu bekommen, ist:
sorted
intersection
set
Oder jene Elemente, die
xyz
aber nicht ina
:Für eine kompliziertere Schleife möchten Sie sie möglicherweise reduzieren, indem Sie einen gut benannten Generatorausdruck durchlaufen und / oder eine gut benannte Funktion aufrufen. Der Versuch, alles in eine Zeile zu bringen, ist selten "Pythonic".
Aktualisieren Sie nach zusätzlichen Kommentaren zu Ihrer Frage und der akzeptierten Antwort
Ich bin nicht sicher, womit Sie versuchen
enumerate
, aber wenna
es sich um ein Wörterbuch handelt, möchten Sie wahrscheinlich die Schlüssel wie folgt verwenden:quelle
Ich persönlich denke, dies ist die schönste Version:
Bearbeiten
Wenn Sie die Verwendung von Lambda vermeiden möchten, können Sie die Teilfunktionsanwendung und das Operatormodul (das die Funktionen der meisten Operatoren bereitstellt) verwenden.
https://docs.python.org/2/library/operator.html#module-operator
quelle
filter(a.__contains__, xyz)
. Wenn Menschen Lambda verwenden, brauchen sie normalerweise etwas viel Einfacheres.__contains__
ist eine Methode wie jede andere, nur ist es eine spezielle Methode, dh sie kann indirekt von einem Operator (in
in diesem Fall) aufgerufen werden . Es kann aber auch direkt aufgerufen werden, es ist Teil der öffentlichen API. Private Namen werden speziell so definiert, dass sie höchstens einen abschließenden Unterstrich haben, um eine Ausnahme für spezielle Methodennamen zu bilden - und sie unterliegen der Namensverfälschung, wenn sie lexikalisch in Klassenbereichen verwendet werden. Siehe docs.python.org/3/reference/datamodel.html#specialnames und docs.python.org/3.6/tutorial/classes.html#private-variables .in
zugegriffen werden kann, scheinen seltsam (Operatoren werden normalerweise verwendet, wenn ein doppelter Versand erforderlich ist, aber einfach mit dem richtigen Operanden versendet wird ). Beachten Sie außerdem, dassoperator
auch diecontains
Methode unter dem Namen exportiert wird__contains__
, sodass es sich sicherlich nicht um einen privaten Namen handelt. Ich denke, Sie müssen nur lernen, damit zu leben, dass nicht jeder doppelte Unterstrich "fernhalten" bedeutet. : -]lambda
Bedürfnisse müssennot
lambda w: not w in a, xyz
Das Folgende ist eine Vereinfachung / ein Liner aus der akzeptierten Antwort:
Beachten Sie, dass das inline
generator
gehalten wurde . Dies wurde am und getestet (beachten Sie die Parens in der ;))python2.7
python3.6
print
quelle
Ich würde wahrscheinlich verwenden:
quelle
pythonic
Ergebnisse. Ich kann funktional in jeder anderen Sprache codieren, die ich benutze (Scala, Kotlin, Javascript, R, Swift, ..), aber schwierig / umständlich in Pythonquelle
import time a = [2,3,4,5,6,7,8,9,0] xyz = [0,12,4,6,242,7,9] start = time.time() print (set(a) & set(xyz)) print time.time() - start
if x in ignore: ...
.if set(a) - set(ignore) == set([]):
vielleicht war es deshalb viel langsamer als die Überprüfung der Mitgliedschaft. Ich werde dies in Zukunft an einem viel einfacheren Beispiel erneut testen als das, was ich schreibe.Sie können auch Generatoren verwenden , wenn Generatorausdrücke zu kompliziert oder zu komplex werden:
quelle
Verwenden Sie
intersection
oderintersection_update
Kreuzung :
intersection_update :
dann
b
ist deine Antwortquelle
Ich mochte Alex 'Antwort , weil ein Filter genau dann eine Liste ist, wenn er auf eine Liste angewendet wird. Wenn Sie also eine Teilmenge einer Liste unter bestimmten Bedingungen untersuchen möchten, scheint dies der natürlichste Weg zu sein
Diese Methode ist nützlich für die Trennung von Bedenken. Wenn sich die Bedingungsfunktion ändert, ist der einzige Code, mit dem Sie herumspielen können, die Funktion selbst
Die Generatormethode scheint besser zu sein, wenn Sie keine Mitglieder der Liste möchten, sondern eine Modifikation dieser Mitglieder, die für einen Generator besser geeignet zu sein scheint
Filter funktionieren auch mit Generatoren, obwohl dies in diesem Fall nicht effizient ist
Aber natürlich wäre es trotzdem schön, so zu schreiben:
quelle
Ein einfacher Weg, um eindeutige gemeinsame Elemente der Listen a und b zu finden:
quelle