¿Cómo puedo usar una expresión condicional (expresión con if y else) en una lista de comprensión? [duplicate]

4 minutos de lectura

avatar de usuario
ducina

Tengo una lista de comprensión que produce una lista de números impares de un rango dado:

[x for x in range(1, 10) if x % 2]

Eso hace un filtro que elimina los números pares. En cambio, me gustaría usar la lógica condicional, de modo que los números pares se traten de manera diferente, pero aun así contribuyan a la lista. Intenté este código, pero falla:

>>> [x for x in range(1, 10) if x % 2 else x * 100]
  File "<stdin>", line 1
    [x for x in range(1, 10) if x % 2 else x * 100]
                                         ^
SyntaxError: invalid syntax

Sé que las expresiones de Python permiten una sintaxis como esa:

1 if 0 is 0 else 3

¿Cómo puedo usarlo dentro de la lista de comprensión?

  • Me tomó un tiempo entender por qué if x % 2 elimina números pares (en lugar de mantenerlos) — es porque cuando x es incluso el x % 2 la expresión da como resultado 0que, a su vez, se evalúa como Falsemientras que cualquier int excepto 0 evalúa a True.

    usuario8554766

    18 de julio de 2018 a las 6:45

avatar de usuario
shx2

x if y else z es la sintaxis de la expresión que devuelve para cada elemento. Por lo tanto, necesita:

[ x if x%2 else x*100 for x in range(1, 10) ]

La confusión surge del hecho de que estás usando un filtrar en el primer ejemplo, pero no en el segundo. En el segundo ejemplo solo estás cartografía cada valor a otro, utilizando una expresión de operador ternario.

Con un filtro, necesitas:

[ EXP for x in seq if COND ]

Sin filtro necesitas:

[ EXP for x in seq ]

y en su segundo ejemplo, la expresión es “compleja”, lo que implica un if-else.

  • tengo una pregunta… [x for x in range(1, 10) if x % 2] es la sintaxis correcta. [x if x % 2 for x in range(1, 10)] – esto no es, pero [x if x%2 else x*100 for x in range(1, 10)] es de nuevo, sintaxis correcta. ¿Cómo?

    – ducina

    26 de junio de 2013 a las 13:26

  • @tkoomzaaskz en su segundo ejemplo, este no es un operador ternario si no (falta el else), ni un filtro (ya que está en el EXP parte de la lista de comprensión)

    – shx2

    8 de mayo de 2015 a las 10:29

  • @tkoomzaaskz Para aclarar más, tenga en cuenta que puede agregar un segundo if al final: [x if x%2 else x*100 for x in range(1, 10) if not x%3] El primero if es parte del operador ternario, el segundo if es parte de la sintaxis de comprensión de listas. El conjunto x if x%2 else x*100 está “al mismo nivel” que un simple 2*xes la expresión a evaluar en el lado izquierdo de la forcuando el filtrado de if not x%3 ya ha tenido lugar.

    – zx81

    1 de julio de 2015 a las 3:14


  • Hola, una declaración de una línea sería más eficaz que hacerla en dos líneas como for i in x: y luego en el bucle for if i == y: ?

    – Alexis.Rolland

    18 de julio de 2018 a las 6:29

[x if x % 2 else x * 100 for x in range(1, 10) ]

avatar de usuario
Stefan Grünwald

También puedes hacer eso con la comprensión de listas:

A=[[x*100, x][x % 2 != 0] for x in range(1,11)]
print A

  • Muy agradable. Una porción booleana. Gracias, me diste una solución más fácil de leer.

    usuario1121588

    08/11/2015 a las 23:00

  • También puede asignar dos veces así: A,B = [10,11][a==19],[1,14][a==20]

    – Stefan Grünwald

    30 de noviembre de 2015 a las 3:53

Solo otra solución, espero que a alguien le guste:

Usando: [False, True][Expression]

>>> map(lambda x: [x*100, x][x % 2 != 0], range(1,10))
[1, 200, 3, 400, 5, 600, 7, 800, 9]
>>>

avatar de usuario
Mido

#cómo puedes cuadrar una lista de una matriz de valores negativos y positivos

my_list=[-2,-3,0,1,5]
squred_values=[]
  

squred_values=[-i**2 if i<0 else i**2 for i in my_list]

#o

for i in my_list:
    if i<0:
        squred_values.append( -i**2)`enter code here`
    else:
        squred_values.append( i**2) 

avatar de usuario
Tomerikoo

dos por en una lista de comprensión

ex = [['obi', 'is', '#alive'],['oge', 'is', 'beautiful'],
                ['Ade', 'the', '#comedian', 'de', '#rich'],['Jesus', 'wept']]
res = [j if j.startswith("#") else "_"+j for i in ex for j in i]

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad