Operador Ternario de Python Sin más


82

¿Es posible hacer esto en una línea en Python?

if <condition>:
    myList.append('myString')

He probado el operador ternario:

myList.append('myString' if <condition>)

pero a mi IDE ( MyEclipse ) no le gustó, sin un else.


¿Te refieres a un operador ternario que no tiene tres partes? ¿No es esto una contradicción de términos?
Marqués de Lorne

Respuestas:


115

Sí, usted puede hacer esto:

<condition> and myList.append('myString')

Si <condition>es falso, entonces se activará el cortocircuito y no se evaluará el lado derecho. Si <condition>es verdadero, se evaluará el lado derecho y se agregará el elemento.

Solo señalaré que hacer lo anterior es bastante no pitónico, y probablemente sea mejor escribir esto, independientemente:

if <condition>: myList.append('myString')

Demostración:

>>> myList = []
>>> False and myList.append('myString')
False
>>> myList
[]
>>> True and myList.append('myString')
>>> myList
['myString']

9
Si bien esta respuesta es técnicamente correcta, no es una buena práctica de programación. Dado que Python pretende ser un lenguaje de fácil lectura, este código se consideraría no Pythonic.
Sr. Lance E Sloan

9
@LS: Estoy de acuerdo, por eso dije que probablemente sería mejor usar una declaración if. Pero modifiqué un poco la respuesta para aclararlo.
Claudiu

2
Para su información, el segundo ejemplo fallará en las comprobaciones de pep8: E701 multiple statements on one linepor lo que también no es pitónico ...;)
Cas

1
@hard_working_ant La forma "correcta" sería x = object.get('attribute')en ese caso
wihlke

1
@wihlke: sí y además agregando x = object.get ('atributo', Ninguno) al valor predeterminado Ninguno
hard_working_ant

43

La razón por la que el idioma no te permite usar la sintaxis

variable = "something" if a_condition

sin elsees eso, en el caso donde a_condition == False, de variablerepente se desconoce. Tal vez podría ser predeterminado None, pero Python requiere que todas las asignaciones de variables realmente resulten en asignaciones explícitas. Esto también se aplica a casos como la llamada a la función, ya que el valor pasado a la función se evalúa como lo sería el RHS de una instrucción de asignación.

De manera similar, todos los returns deben retornar realmente, incluso si son returns condicionales . P.ej:

return variable if a_condition

no está permitido, pero

return variable if a_condition else None

está permitido, ya que se garantiza que el segundo ejemplo devolverá algo explícitamente.


1
Es irónico cómo Python no nos permite usar esto para que la variable nunca sea ninguna, pero variable=Nonees perfectamente legal. : D
Guy

1
Pero quería usarlo así: continue if i == 0en un bucle for.
Karantan

2
¿Se le permite hacerelse pass?
OldBunny2800

5
else passno funciona porque la expresión ternaria debe devolver un valor al que se puede pasar return. passno es un returnvalor válido .
Emmett Butler

4
No estoy de acuerdo que esta motivación es la verdadera razón, dado que if a_condition: variable = "something"y if a_condition: return variableson legales. Entonces, es esencialmente una elección sintáctica arbitraria de Python.
oulenz

13
if <condition>: myList.append('myString')

De otra manera no. ¿Por qué la necesidad de ponerlo en una línea?

Tenga en cuenta que el "operador ternario" es un operador . Como cualquier operador, debe devolver algo , entonces, ¿cómo puede tener un operador ternario sin la elsecláusula? ¿Qué se supone que debe devolver si la condición no es verdadera?


10

Básicamente, estás pidiendo una do_thing() if <condition> else passconstrucción (que se lanzará SyntaxError, si se ejecuta). Como descubrí durante la investigación, una pregunta (algo) similardo_thing() if condition else None es lo más cercana posible (que es solo otra forma de hacerlo <condition> and do_thing()). Entonces, para resumir esta idea y otras respuestas, estas son sus opciones:

  • if <condition>: myList.append('myString') - parece ser la forma menos 'hacky' (y por lo tanto preferida)
  • <condition> and myList.append('myString')
  • myList.append('myString') if <condition> else None

La forma menos hacker no funciona. Al menos no en el REPL: se obtiene un error de sintaxis. Parece que está causado por el código anterior en la misma línea. En su lugar, esto debe ejecutarse en su propia línea. Pero incluso entonces se requiere la entrada del usuario para omitir los puntos suspensivos.
Unknow0059

3

myList.extend(['myString'] if condition else []) también funcionaría, aunque es más trabajo que las otras soluciones.


0

Puedes hacer algo como esto:

myList.append('myString') if <condition> else False

o

myList.append('myString') if <condition> else 0

False y 0 no se agregan a la lista. La línea solo necesita devolver algo si no se cumple la condición. Puede reemplazar el 0 o Falso con Ninguno o una cadena vacía, o cualquier cosa que desee, y no afectará la lista.
Zachary Chiodini

Creo que mi pensamiento en ese momento fue en el caso de una lista de comprensión. Borré mi comentario, el voto negativo no era yo. Supongo que una forma más limpia sería hacerlo. myList.append('myString') if True else _Pero si no estás asignando nada, no importa. Sin embargo, me preocupa que esta persona intente una lista de comprensión con una lógica similar.
Dave Liu

0

Solo haría esto si quiero agregar elementos opcionales a una lista basada en una condición.

nums = [
        1,
        2,
        3 if <condition> else None,
        4,
       ]
nums = [i for i in nums if i is not None]

esto simplemente reemplaza el valor con Ninguno si no se cumple la condición y luego, simplemente redefine la lista sin los Valores Ninguno. de esta manera conservan su índice si se cumple la condición

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.