Python forma de combinar bucle FOR y SI la instrucción


Sé cómo usar tanto los bucles for como las sentencias if 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 sentencias if. Algo que yo esperaría se parece a:

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

Es ¿esta no es la forma en que se supone que funciona Python?

Author: simonzack, 2011-08-08

8 answers

Puedes usar expresiones generadoras así:

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

for x in gen:
    print x
 236
Author: Kugel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-08 12:19:52

Según El Zen de Python (si te estás preguntando si tu código es "Pitónico", ese es el lugar para ir):

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

El Python el modo de conseguir el sorted intersection de dos sets 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 de generador bien llamada y/o llamando a una función bien llamada. Tratar de encajar todo en una línea rara vez es "Pitónico".


Actualización después de comentarios adicionales sobre su pregunta y la respuesta aceptada

No estoy seguro de lo que estás tratando de hacer con enumerate, pero si a es un diccionario, probablemente quieras para usar las teclas, así:

>>> 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
 27
Author: Johnsyweb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-08 22:15:13

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 usar el módulo 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)))
 11
Author: Alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-07 13:06:02
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])
 9
Author: Kracekumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-03 06:48:27

Probablemente usaría:

for x in xyz: 
    if x not in a:
        print x...
 9
Author: Wim Feijen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-19 11:59:57

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

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

for x in gen():
    print x
 4
Author: Lauritz V. Thaulow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-08 12:05:35

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 inline. Esto fue probado en python2.7 y python3.6 (observe los paréntesis en el print ;) )

 3
Author: javadba,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-23 02:33:06

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

 2
Author: Chung-Yen Hung,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-27 12:12:23