Sé cómo usar tanto para bucles como para declaraciones en líneas separadas, como:
>>> 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
Y sé que puedo usar una comprensión de lista para combinarlos cuando las declaraciones son simples, como:
print([x for x in xyz if x in a])
Pero lo que no puedo encontrar es un buen ejemplo en cualquier lugar (para copiar y aprender) que demuestre un conjunto complejo de comandos (no solo "imprimir x") que ocurren después de una combinación de un bucle for y algunas declaraciones if. Algo que esperaría se ve así:
for x in xyz if x not in a:
print(x...)
¿No es así como se supone que funciona Python?
python
loops
if-statement
for-loop
ChewyChunks
fuente
fuente
for
ciclo explícito yif
declaración.x in a
es lento sia
es una lista.Respuestas:
Puede usar expresiones generadoras como esta:
fuente
gen = (y for (x,y) in enumerate(xyz) if x not in a)
devuelve >>>12
cuando escribofor x in gen: print x
, entonces, ¿por qué el comportamiento inesperado con enumerate?for x in xyz if x:
for x in (x for x in xyz if x not in a):
funciona para mí, pero por qué no deberías poder hacerlofor x in xyz if x not in a:
, no estoy seguro ...Según The Zen of Python (si se pregunta si su código es "Pythonic", ese es el lugar para ir):
La forma pitónica de obtener el de dos s es:
sorted
intersection
set
O aquellos elementos que están
xyz
pero no ena
:Pero para un ciclo más complicado, es posible que desee aplanarlo iterando sobre una expresión generadora bien nombrada y / o llamando a una función bien nombrada. Tratar de encajar todo en una línea rara vez es "Pythonic".
Actualice los siguientes comentarios adicionales sobre su pregunta y la respuesta aceptada
No estoy seguro de lo que está tratando de hacer
enumerate
, pero sia
es un diccionario, probablemente quiera usar las teclas, como esta:fuente
Personalmente, creo que esta es la versión más bonita:
Editar
Si está muy interesado en evitar el uso de lambda, puede usar la aplicación de función parcial y usar el módulo de operador (que proporciona las funciones de la mayoría de los operadores).
https://docs.python.org/2/library/operator.html#module-operator
fuente
filter(a.__contains__, xyz)
. Por lo general, cuando las personas usan lambda, realmente necesitan algo mucho más simple.__contains__
es un método como cualquier otro, solo que es un método especial , lo que significa que puede ser llamado indirectamente por un operador (in
en este caso). Pero también se puede llamar directamente, es parte de la API pública. Los nombres privados se definen específicamente como que tienen como máximo un guión bajo final, para proporcionar una excepción para los nombres de métodos especiales, y están sujetos a cambios de nombre cuando léxicamente en los ámbitos de clase. Ver docs.python.org/3/reference/datamodel.html#specialnames y docs.python.org/3.6/tutorial/classes.html#private-variables .in
se despacha individualmente con el operando correcto). Además, tenga en cuenta queoperator
también exporta elcontains
método bajo el nombre__contains__
, por lo que seguramente no es un nombre privado. Creo que solo tendrás que aprender a vivir con el hecho de que no todos los guiones bajos dobles significan "mantente alejado". : -]lambda
necesidades de reparación para incluirnot
:lambda w: not w in a, xyz
La siguiente es una simplificación / una línea de la respuesta aceptada:
Tenga en cuenta que
generator
se mantuvo en línea . Esto se probópython2.7
ypython3.6
(observe los padres en elprint
;))fuente
Probablemente usaría:
fuente
pythonic
resultados. Puedo codificar funcionalmente en cualquier otro idioma que use (scala, kotlin, javascript, R, swift, ..) pero difícil / incómodo en pythonfuente
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([]):
lo que tal vez es por eso que fue mucho más lento que el control de la pertenencia Voy a probar esto de nuevo en el futuro en un ejemplo mucho más simple que lo que estoy escribiendo..También puede usar generadores , si las expresiones generadoras se vuelven demasiado complicadas o complejas:
fuente
Use
intersection
ointersection_update
intersección :
intersection_update :
entonces
b
es tu respuestafuente
Me gustó la respuesta de Alex , porque un filtro es exactamente si se aplica a una lista, por lo que si desea explorar un subconjunto de una lista dada una condición, esta parece ser la forma más natural
Este método es útil para la separación de inquietudes, si la función de condición cambia, el único código para jugar es la función en sí
El método generador parece mejor cuando no desea miembros de la lista, pero una modificación de dichos miembros, que parece más adecuada para un generador
Además, los filtros funcionan con generadores, aunque en este caso no es eficiente
Pero, por supuesto, aún sería bueno escribir así:
fuente
Una manera simple de encontrar elementos comunes únicos de las listas a y b:
fuente