Forma pythonica de combinar el bucle FOR y la statement IF.

Sé cómo usar los bucles y las declaraciones if en líneas separadas, como por ejemplo:

>>> 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 lista de comprensión para combinar esto cuando las declaraciones son simples, como por ejemplo:

 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 muestre un conjunto complejo de comandos (no solo “imprimir x”) que se producen después de una combinación de un bucle for y algunas declaraciones if. Algo que yo esperaría se ve como:

 for x in xyz if x not in a: print(x...) 

¿No es así como se supone que funciona Python?

Puedes usar expresiones generadoras como esta:

 gen = (x for x in xyz if x not in a) for x in gen: print x 

Según el Zen de Python (si te estás preguntando si tu código es “Pythonic”, ese es el lugar para ir):

  • Lo bello es mejor que lo feo.
  • Explícito es mejor que implícito.
  • Lo simple es mejor que lo complejo.
  • Plano es mejor que nested.
  • La legibilidad cuenta.

La forma Pythonic de obtener la intersection sorted de dos set s es:

 >>> sorted(set(a).intersection(xyz)) [0, 4, 6, 7, 9] 

O aquellos elementos que son xyz pero no en a :

 >>> sorted(set(xyz).difference(a)) [12, 242] 

Pero para un bucle 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”.


Actualización siguiendo los comentarios adicionales sobre su pregunta y la respuesta aceptada

No estoy seguro de qué intentas hacer con enumerate , pero si a es un diccionario, probablemente quieras usar las claves, como esto:

 >>> a = { ... 2: 'Turtle Doves', ... 3: 'French Hens', ... 4: 'Colly Birds', ... 5: 'Gold Rings', ... 6: 'Geese-a-Laying', ... 7: 'Swans-a-Swimming', ... 8: 'Maids-a-Milking', ... 9: 'Ladies Dancing', ... 0: 'Camel Books', ... } >>> >>> xyz = [0, 12, 4, 6, 242, 7, 9] >>> >>> known_things = sorted(set(a.iterkeys()).intersection(xyz)) >>> unknown_things = sorted(set(xyz).difference(a.iterkeys())) >>> >>> for thing in known_things: ... print 'I know about', a[thing] ... I know about Camel Books I know about Colly Birds I know about Geese-a-Laying I know about Swans-a-Swimming I know about Ladies Dancing >>> print '...but...' ...but... >>> >>> for thing in unknown_things: ... print "I don't know what happened on the {0}th day of Christmas".format(thing) ... I don't know what happened on the 12th day of Christmas I don't know what happened on the 242th day of Christmas 

Personalmente creo que esta es la versión más bonita:

 a = [2,3,4,5,6,7,8,9,0] xyz = [0,12,4,6,242,7,9] for x in filter(lambda w: w in a, xyz): print x 

Editar

Si está muy interesado en evitar usar lambda, puede usar la aplicación de función parcial y el módulo de operador (que proporciona funciones de la mayoría de los operadores).

https://docs.python.org/2/library/operator.html#module-operator

 from operator import contains from functools import partial print(list(filter(partial(contains, a), xyz))) 
 a = [2,3,4,5,6,7,8,9,0] xyz = [0,12,4,6,242,7,9] set(a) & set(xyz) set([0, 9, 4, 6, 7]) 

Probablemente usaría:

 for x in xyz: if x not in a: print x... 

Lo siguiente es una simplificación / una línea de la respuesta aceptada:

 a = [2,3,4,5,6,7,8,9,0] xyz = [0,12,4,6,242,7,9] for x in (x for x in xyz if x not in a): print(x) 12 242 

Observe que el generator se mantuvo en línea . Esto se probó en python2.7 y python3.6 (observe los parens en la print ;))

También puede usar generadores , si las expresiones del generador se vuelven demasiado complejas o complejas:

 def gen(): for x in xyz: if x in a: yield x for x in gen(): print x 

Use intersection o intersection_update

  • intersección

     a = [2,3,4,5,6,7,8,9,0] xyz = [0,12,4,6,242,7,9] ans = sorted(set(a).intersection(set(xyz))) 
  • intersection_update :

     a = [2,3,4,5,6,7,8,9,0] xyz = [0,12,4,6,242,7,9] b = set(a) b.intersection_update(xyz) 

    entonces b es tu respuesta