que - ¿Python tiene un operador condicional ternario?
que es un operador ternario en programacion (23)
Si Python no tiene un operador condicional ternario, ¿es posible simular uno usando otras construcciones de lenguaje?
¿Python tiene un operador condicional ternario?
Sí. Desde el archivo de gramática :
test: or_test [''if'' or_test ''else'' test] | lambdef
La parte de interés es:
or_test [''if'' or_test ''else'' test]
Así, una operación condicional ternaria es de la forma:
expression1 if expression2 else expression3
expression3
se evaluará perezosamente (es decir, se evaluará solo si expression2
es falsa en un contexto booleano). Y debido a la definición recursiva, puede encadenarlos indefinidamente (aunque puede considerarse un estilo malo).
expression1 if expression2 else expression3 if expression4 else expression5 # and so on
Una nota sobre el uso:
Tenga en cuenta que cada if
debe ser seguido con un else
. La comprensión de las listas de aprendizaje de las personas y las expresiones generadoras pueden encontrar que esta es una lección difícil de aprender; lo siguiente no funcionará, ya que Python espera una tercera expresión para otra cosa:
[expression1 if expression2 for element in iterable]
# ^-- need an else here
que plantea un SyntaxError: invalid syntax
. Por lo tanto, lo anterior es una pieza de lógica incompleta (tal vez el usuario espera una no-op en la condición falsa) o lo que se pretende es usar expresión2 como filtro. Observa que lo siguiente es legal de Python:
[expression1 for element in iterable if expression2]
expression2
funciona como un filtro para la comprensión de la lista y no es un operador condicional ternario.
Sintaxis alternativa para un caso más estrecho:
Puede resultarle un poco doloroso escribir lo siguiente:
expression1 if expression1 else expression2
expression1
tendrá que evaluarse dos veces con el uso anterior. Puede limitar la redundancia si es simplemente una variable local. Sin embargo, un lenguaje Pythonic común y eficaz para este caso de uso es usar or
el método abreviado:
expression1 or expression2
Lo cual es equivalente en semántica. Tenga en cuenta que algunas guías de estilo pueden limitar este uso por razones de claridad, ya que contienen mucho significado en muy poca sintaxis.
Operador Ternario en diferentes lenguajes de programación.
Aquí solo trato de mostrar alguna diferencia importante en el ternary operator
entre un par de lenguajes de programación.
Operador Ternario en Javascript
var a = true ? 1 : 0;
# 1
var b = false ? 1 : 0;
# 0
Operador Ternario en Ruby
a = true ? 1 : 0
# 1
b = false ? 1 : 0
# 0
Operador ternario en Scala
val a = true ? 1 | 0
# 1
val b = false ? 1 | 0
# 0
Operador ternario en programación r
a <- if (TRUE) 1 else 0
# 1
b <- if (FALSE) 1 else 0
# 0
Operador ternario en Python
a = 1 if True else 0
# 1
b = 1 if False else 0
# 0
Ahora puedes ver la belleza del lenguaje python. Es altamente legible y mantenible.
@arriba:
Desafortunadamente, el
(falseValue, trueValue)[test]
La solución no tiene un comportamiento de cortocircuito; por lo tanto, tanto falseValue como trueValue se evalúan independientemente de la condición. Esto podría ser subóptimo o incluso con errores (es decir, tanto trueValue como falseValue podrían ser métodos y tener efectos secundarios).
Una solución para esto sería
(lambda: falseValue, lambda: trueValue)[test]()
(la ejecución se retrasa hasta que se conoce al ganador;)), pero introduce inconsistencia entre los objetos que se pueden llamar y los que no se pueden llamar. Además, no resuelve el caso cuando se utilizan propiedades.
Y así continúa la historia: elegir entre las 3 soluciones mencionadas es un compromiso entre tener la función de cortocircuito, usar al menos Python 2.5 (IMHO ya no es un problema) y no ser propenso a "trueValue-evalates-to-false" errores
A menudo puede encontrar
cond and on_true or on_false
pero esto lleva al problema cuando on_true == 0
>>> x = 0
>>> print x == 0 and 0 or 1
1
>>> x = 1
>>> print x == 0 and 0 or 1
1
donde se esperaría para un operador ternario normal este resultado
>>> x = 0
>>> print 0 if x == 0 else 1
0
>>> x = 1
>>> print 0 if x == 0 else 1
1
Absolutamente, y es increíblemente fácil de entender.
general syntax : first_expression if bool_expression_is_true else second_expression
Example: x= 3 if 3 > 2 else 4
# assigns 3 to x if the boolean expression evaluates to true or 4 if it is false
De la documentación :
Las expresiones condicionales (a veces llamadas "operadores ternarios") tienen la prioridad más baja de todas las operaciones de Python.
La expresión
x if C else y
primero evalúa la condición, C ( no x ); si C es verdadero, se evalúa x y se devuelve su valor; de lo contrario, se evalúa y y se devuelve su valor.Vea PEP 308 para más detalles sobre expresiones condicionales.
Nuevo desde la versión 2.5.
El operador condicional ternario simplemente permite probar una condición en una sola línea, reemplazando la multilínea if-else haciendo que el código sea compacto.
Sintaxis:
[on_true] si [expresión] else [on_false]
1- Método simple para usar el operador ternario:
# Program to demonstrate conditional operator
a, b = 10, 20
# Copy value of a in min if a < b else copy b
min = a if a < b else b
print(min) # Output: 10
2- Método directo de uso de tuplas, diccionario y lambda:
# Python program to demonstrate ternary operator
a, b = 10, 20
# Use tuple for selecting an item
print( (b, a) [a < b] )
# Use Dictionary for selecting an item
print({True: a, False: b} [a < b])
# lamda is more efficient than above two methods
# because in lambda we are assure that
# only one expression will be evaluated unlike in
# tuple and Dictionary
print((lambda: b, lambda: a)[a < b]()) # in output you should see three 10
3- El operador ternario se puede escribir como anidado if-else:
# Python program to demonstrate nested ternary operator
a, b = 10, 20
print ("Both a and b are equal" if a == b else "a is greater than b"
if a > b else "b is greater than a")
El enfoque anterior se puede escribir como:
# Python program to demonstrate nested ternary operator
a, b = 10, 20
if a != b:
if a > b:
print("a is greater than b")
else:
print("b is greater than a")
else:
print("Both a and b are equal")
# Output: b is greater than a
Más una sugerencia que una respuesta (no es necesario repetir lo obvio por centésimo tiempo), pero a veces lo uso como un atajo de oneliner en tales construcciones:
if conditionX:
print(''yes'')
else:
print(''nah'')
, se convierte en:
print(''yes'') if conditionX else print(''nah'')
Algunos (muchos :) pueden fruncir el entrecejo como algo antipónico (incluso, ruby-ish :), pero personalmente lo encuentro más natural, es decir, cómo lo expresaría normalmente, además de un poco más atractivo visualmente en grandes bloques de código.
Para Python 2.5 y posteriores hay una sintaxis específica:
[on_true] if [cond] else [on_false]
En Pythons más antiguos no se implementa un operador ternario, pero es posible simularlo.
cond and on_true or on_false
Sin embargo, hay un problema potencial, que si cond
evalúa como True
y on_true
evalúa como False
, se devuelve on_true
lugar de on_true
. Si desea este comportamiento, el método es correcto, de lo contrario use esto:
{True: on_true, False: on_false}[cond is True] # is True, not == True
el cual puede ser envuelto por:
def q(cond, on_true, on_false)
return {True: on_true, False: on_false}[cond is True]
y utilizado de esta manera:
q(cond, on_true, on_false)
Es compatible con todas las versiones de Python.
Para versiones anteriores a 2.5, hay un truco:
[expression] and [on_true] or [on_false]
Puede dar resultados incorrectos cuando on_true
tiene un valor booleano falso. 1
Aunque tiene el beneficio de evaluar expresiones de izquierda a derecha, lo que es más claro en mi opinión.
Puede indexar en una tupla:
(falseValue, trueValue)[test]
test
debe devolver verdadero o falso .
Podría ser más seguro implementarlo siempre como:
(falseValue, trueValue)[test == True]
o puede usar el bool()
incorporado bool()
para asegurar un valor Boolean :
(falseValue, trueValue)[bool(<expression>)]
Puedes hacerlo :-
[condition] and [expression_1] or [expression_2] ;
Ejemplo:-
print(number%2 and "odd" or "even")
Esto imprimiría "impar" si el número es impar o "par" si el número es par.
El resultado: - Si la condición es verdadera, exp_1 se ejecuta, de lo contrario se ejecuta exp_2.
Nota: - 0, Ninguno, Falso, lista vacía, emptyString se evalúa como Falso. Y cualquier dato distinto de 0 se evalúa como Verdadero.
Así es como funciona:
si la condición [condición] se convierte en "Verdadero", entonces se evaluará expresión_1 pero no expresión_2. Si "y" algo con 0 (cero), el resultado siempre será fasle. Por lo tanto, en la siguiente declaración,
0 and exp
La expresión exp no se evaluará en absoluto, ya que "y" con 0 siempre se evaluará a cero y no hay necesidad de evaluar la expresión. Así es como funciona el compilador, en todos los idiomas.
En
1 or exp
la expresión exp no se evaluará en absoluto, ya que "o" con 1 siempre será 1. Por lo tanto, no se molestará en evaluar la expresión exp, ya que el resultado será 1 de todos modos. (métodos de optimización del compilador).
Pero en caso de
True and exp1 or exp2
La segunda expresión exp2 no se evaluará ya que True and exp1
serían True si exp1 no es false.
Del mismo modo en
False and exp1 or exp2
La expresión exp1 no se evaluará ya que False es equivalente a escribir 0 y hacer "y" con 0 sería 0 en sí mismo, pero luego de exp1, ya que "o" se usa, evaluará la expresión exp2 después de "o".
Nota: - Este tipo de ramificación con "o" y "y" solo se puede usar cuando la expresión_1 no tiene un valor de Verdad de Falso (o 0 o Ninguno o lista vacía [] o cadena vacía ''''.), Ya que si expresión_1 se convierte en Falso, la expresión_2 se evaluará debido a la presencia "o" entre exp_1 y exp_2.
En caso de que aún desee que funcione para todos los casos, independientemente de los valores de verdad de exp_1 y exp_2, haga lo siguiente:
[condition] and ([expression_1] or 1) or [expression_2] ;
SÍ, Python tiene un operador ternario, aquí está la sintaxis y un código de ejemplo para demostrar lo mismo :)
#[On true] if [expression] else[On false]
# if the expression evaluates to true then it will pass On true otherwise On false
a= input("Enter the First Number ")
b= input("Enter the Second Number ")
print("A is Bigger") if a>b else print("B is Bigger")
Sí, fue added en la versión 2.5.
La sintaxis es:
a if condition else b
La primera condition
se evalúa, luego a
o b
se devuelve según el valor Boolean de condition
Si la condition
evalúa como verdadera, se devuelve una a, de lo contrario se devuelve b
.
Por ejemplo:
>>> ''true'' if True else ''false''
''true''
>>> ''true'' if False else ''false''
''false''
Tenga en cuenta que los condicionales son una expresión , no una declaración . Esto significa que no puede usar asignaciones, pass
u otras declaraciones en un condicional:
>>> pass if False else x = 3
File "<stdin>", line 1
pass if False else x = 3
^
SyntaxError: invalid syntax
En tal caso, tiene que usar una sentencia normal if
lugar de una condicional.
Tenga en cuenta que está mal visto por algunos pitonistas por varias razones:
- El orden de los argumentos es diferente de muchos otros lenguajes (como C, Ruby, Java, etc.), lo que puede provocar errores cuando las personas que no están familiarizadas con el comportamiento "sorprendente" de Python lo usan (pueden invertir el orden).
- Algunos lo consideran "poco manejable", ya que va en contra del flujo normal de pensamiento (pensando primero en la condición y luego en los efectos).
- Razones estilísticas.
Si tiene problemas para recordar el pedido, recuerde que si lo lee en voz alta (casi) dice lo que quiere decir. Por ejemplo, x = 4 if b > 8 else 9
se lee en voz alta ya que x will be 4 if b is greater than 8 otherwise 9
.
Documentación oficial:
Sí, puedes usarlo de esa manera:
is_fat = True
state = "fat" if is_fat else "not fat"
Leer más sobre operador condicional ternario.
Sí.
>>> b = (True if 5 > 4 else False)
>>> print b
True
Sí:
Digamos que quieres darle a la variable x algún valor si alguna bool es verdadera y lo mismo
X = 5 si algo más x = 10
X = [algún valor] si [si esto es cierto, el primer valor evalúa] de lo contrario [otro valor evalúa]
Si la variable está definida y desea verificar si tiene valor, puede simplemente a or b
def test(myvar=None):
# shorter than: print myvar if myvar else "no Input"
print myvar or "no Input"
test()
test([])
test(False)
test(''hello'')
test([''Hello''])
test(True)
dará salida
no Input
no Input
no Input
hello
[''Hello'']
True
Simulando el operador ternario de pitón.
Por ejemplo
a, b, x, y = 1, 2, ''a greather than b'', ''b greater than a''
result = (lambda:y, lambda:x)[a > b]()
salida:
''b greater than a''
Sintaxis: El operador ternario se dará como:
[on_true] if [expression] else [on_false]
p.ej
x, y = 25, 50
big = x if x < y else y
print(big)
Un operador para una expresión condicional en Python se agregó en 2006 como parte de la Propuesta 308 de mejora de Python . ¿Su forma difiere de la común ?:
Operador y es:
<expression1> if <condition> else <expression2>
que es equivalente a:
if <condition>: <expression1> else: <expression2>
Aquí hay un ejemplo:
result = x if a > b else y
Otra sintaxis que se puede usar (compatible con versiones anteriores a 2.5):
result = (lambda:y, lambda:x)[a > b]()
donde los operandos son perezosamente evaluados .
Otra forma es indexando una tupla (que no es consistente con el operador condicional de la mayoría de los otros idiomas):
result = (y, x)[a > b]
o diccionario construido explícitamente:
result = {True: x, False: y}[a > b]
Otro método (menos confiable), pero más simple es usar and
/ or
operadores:
result = (a > b) and x or y
Sin embargo, esto no funcionará si x
sería False
.
Una posible solución es hacer listas x
e y
tuplas como en lo siguiente:
result = ((a > b) and [x] or [y])[0]
o:
result = ((a > b) and (x,) or (y,))[0]
Si está trabajando con diccionarios, en lugar de usar un condicional ternario, puede aprovechar get(key, default)
, por ejemplo:
shell = os.environ.get(''SHELL'', "/bin/sh")
Fuente: ?:
expresión1 si condición más expresión2
>>> a = 1
>>> b = 2
>>> 1 if a > b else -1
-1
>>> 1 if a > b else -1 if a < b else 0
-1
In [1]: a = 1 if False else 0
In [2]: a
Out[2]: 0
In [3]: b = 1 if True else 0
In [4]: b
Out[4]: 1