Pregunta

Si Python no tiene un operador condicional ternario, ¿es posible simular uno utilizando otras construcciones del lenguaje?

¿Fue útil?

Solución

Sí, era añadió en la versión 2.5. La sintaxis de la expresión es:

a if condition else b

Primera condition se evalúa, a continuación, uno de o bien a o b se evalúa exactamente y volvió basado en el valor booleano de condition. Si se evalúa como condition True, entonces a se evalúa y se devuelve pero b se ignora, o bien cuando se evalúa b y regresó, pero se ignora a.

Esto permite un cortocircuito porque cuando condition es cierto sólo se evalúa a y b no se evalúa en absoluto, pero cuando condition es falsa sólo se evalúa b y a no se evalúa en absoluto.

Por ejemplo:

>>> 'true' if True else 'false'
'true'
>>> 'true' if False else 'false'
'false'

Tenga en cuenta que los condicionales son un expresión , no un instrucción . Esto significa que no puede utilizar las instrucciones de asignación o pass u otras declaraciones dentro de un condicional expresión

>>> pass if False else x = 3
  File "<stdin>", line 1
    pass if False else x = 3
          ^
SyntaxError: invalid syntax

Puede, sin embargo, utilizar expresiones condicionales para asignar una variable de esta manera:

x = a if True else b

Piense de la expresión condicional como el cambio entre dos valores. Es muy útil cuando se está en un 'un valor u otro' situación, pero no hace mucho más.

Si es necesario utilizar declaraciones, usted tiene que utilizar un if normales declaración en lugar de un condicional expresión .


Tenga en cuenta que es mal visto por algunos Pythonistas por varias razones:

  • El orden de los argumentos es diferente de las del operador ternario condition ? a : b clásico de muchos otros lenguajes (como C, C ++, Go, Perl, Ruby, Java, JavaScript, etc.), lo que puede conducir a errores cuando la gente familiarizados con el comportamiento de "sorprendente" de Python lo utilizan (que pueden revertir el orden de los argumentos).
  • Para algunas personas es "difícil de manejar", ya que va en contra de la corriente normal de pensamiento (pensamiento de la condición primera y luego los efectos).
  • razones estilísticas. (Aunque el 'inline if' puede ser realmente útil, y hacer su escritura más concisa, lo que realmente complica su código)

Si usted está teniendo problemas para recordar el orden, a continuación, recordar que cuando se lee en voz alta, que (casi) diga lo que quiere decir. Por ejemplo, x = 4 if b > 8 else 9 se lee en voz alta como x will be 4 if b is greater than 8 otherwise 9.

La documentación oficial:

Otros consejos

Es posible indexar en una tupla:

(falseValue, trueValue)[test]

test necesita volver True o false .
Podría ser más seguro para poner en práctica siempre como:

(falseValue, trueValue)[test == True]

o puede utilizar el incorporado en la bool() para asegurar una valor booleano :

(falseValue, trueValue)[bool(<expression>)]

En versiones anteriores a 2.5, está el truco:

[expression] and [on_true] or [on_false]

Se puede dar resultados erróneos cuando on_true  tiene un valor booleano falso. 1
Aunque tiene el beneficio de la evaluación de expresiones de izquierda a derecha, lo que es más claro en mi opinión.

1. href="http://docs.python.org/3.3/faq/programming.html#is-there-an-equivalent-of-cs-ternary-operator" ¿Hay un equivalente de C “:?”? operador ternario

<expression 1> if <condition> else <expression 2>

a = 1
b = 2

1 if a > b else -1 
# Output is -1

1 if a > b else -1 if a < b else 0
# Output is -1

la documentación:

  

Las expresiones condicionales (a veces llamado un “operador ternario”) tienen la prioridad más baja de todas las operaciones de Python.

     

El x if C else y expresión se evalúa primero la condición, C ( no x ); si C es cierto, x se evalúa y se devuelve su valor; de lo contrario, y se evalúa y se devuelve su valor.

     

PEP 308 para más detalles acerca de las expresiones condicionales.

Nuevo desde la versión 2.5.

Un operador para una expresión condicional en Python se añadió en 2006 como parte de Enhancement Python propuesta 308 . Su forma difiere de operador ?: común y que es:

<expression1> if <condition> else <expression2>

que es equivalente a:

if <condition>: <expression1> else: <expression2>

Aquí es un ejemplo:

result = x if a > b else y

Otra sintaxis que se puede utilizar (compatible con versiones antes de 2.5):

result = (lambda:y, lambda:x)[a > b]()

donde operandos son perezosamente evaluado .

Otra forma es mediante la indexación de una tupla (que no es consistente con el operador condicional de la mayoría de otros idiomas):

result = (y, x)[a > b]

o diccionario construido explícitamente:

result = {True: x, False: y}[a > b]

Otro método (menos fiables), pero más simple es utilizar los operadores and y or:

result = (a > b) and x or y

Sin embargo, esto no funcionará si se x False.

Una posible solución consiste en hacer listas o tuplas x y y como en el siguiente:

result = ((a > b) and [x] or [y])[0]

o

result = ((a > b) and (x,) or (y,))[0]

Si se trabaja con los diccionarios, en lugar de utilizar un condicional ternario, se puede tomar ventaja de get(key, default) , por ejemplo:

shell = os.environ.get('SHELL', "/bin/sh")

Fuente: :? En Python en Wikipedia

Por desgracia, la

(falseValue, trueValue)[test]

solución no tiene el comportamiento de cortocircuito; por lo tanto se evalúan tanto falseValue y trueValue independientemente de la condición. Esto podría ser subóptima o incluso con errores (es decir, tanto trueValue y falseValue podrían ser métodos y tienen efectos secundarios).

Una solución a esto sería

(lambda: falseValue, lambda: trueValue)[test]()

(ejecución retrasa hasta que se conoce el ganador;)), pero introduce inconsistencia entre los objetos desembolsadas y no exigible. Además, no resuelve el caso cuando se utilizan las propiedades.

Y así va la historia - la elección entre 3 soluciones mencionadas es una solución de compromiso entre tener la función de cortocircuito, utilizando al menos Зython 2.5 (en mi humilde opinión no es un problema ya) y no ser propenso a "trueValue-evalúa a " errores es falsa.

ternario Operador de programación diferentes idiomas

A continuación, sólo trato de mostrar alguna diferencia importante en ternary operator entre un par de lenguajes de programación.

  

ternario operador en Javascript

var a = true ? 1 : 0;
# 1
var b = false ? 1 : 0;
# 0
  

ternario operador 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 la 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

En Python 2.5 y más reciente hay una sintaxis específica:

[on_true] if [cond] else [on_false]

En pitones un operador ternario de más edad no está implementado pero es posible simularlo.

cond and on_true or on_false

Sin embargo, existe un problema potencial, que si se evalúa como cond True y on_true evalúa a continuación False on_false se devuelve en lugar de on_true. Si desea que este comportamiento del método está bien, de lo contrario usar esto:

{True: on_true, False: on_false}[cond is True] # is True, not == True

que puede ser envuelto por:

def q(cond, on_true, on_false)
    return {True: on_true, False: on_false}[cond is True]

y se utiliza de esta manera:

q(cond, on_true, on_false)

Es compatible con todas las versiones de Python.

Es posible que a menudo se encuentran

cond and on_true or on_false

pero esto conduce a un problema cuando == 0 on_true

>>> x = 0
>>> print x == 0 and 0 or 1 
1
>>> x = 1
>>> print x == 0 and 0 or 1 
1

donde se puede esperar de un operador ternario normal de este resultado

>>> x = 0
>>> print 0 if x == 0 else 1 
0
>>> x = 1
>>> print 0 if x == 0 else 1 
1
  

¿Tiene Python tiene un operador condicional ternario?

Sí. Desde el :

test: or_test ['if' or_test 'else' test] | lambdef

La parte de interés es:

or_test ['if' or_test 'else' test]

Por lo tanto, una operación condicional ternario es de la forma:

expression1 if expression2 else expression3

expression3 será evaluada perezosamente (es decir, evalúa sólo si expression2 es falso en un contexto booleano). Y debido a la definición recursiva, se les puede encadenar de forma indefinida (aunque puede considerarse un mal estilo.)

expression1 if expression2 else expression3 if expression4 else expression5 # and so on

Nota sobre el uso:

Tenga en cuenta que cada if debe ser seguido con un else. Personas que están aprendiendo listas por comprensión y expresiones generadoras pueden encontrar que esto sea una lección difícil de aprender - la siguiente no funcionará, como Python espera una tercera expresión de una cosa:

[expression1 if expression2 for element in iterable]
#                          ^-- need an else here

lo que plantea un SyntaxError: invalid syntax. Así que la anterior es o bien una pieza incompleta de la lógica (tal vez el usuario espera un no-op en la condición falso) o lo puede estar destinado es utilizar expression2 como un filtro - observa que la siguiente es Python legal:

[expression1 for element in iterable if expression2]

expression2 funciona como un filtro para la lista de la comprensión, y es no un operador condicional ternario.

Sintaxis alternativa para un caso más estrecha:

Puede resultar algo doloroso para escribir lo siguiente:

expression1 if expression1 else expression2

expression1 tendrá que ser evaluado dos veces con el uso anteriormente. Se puede limitar la redundancia si es simplemente una variable local. Sin embargo, un lenguaje común y Pythonic performant para este caso de uso es utilizar el comportamiento acortando de or:

expression1 or expression2

que es equivalente en la semántica. Tenga en cuenta que algunas guías de estilo pueden limitar este uso por motivos de claridad -. Sí paquete de un montón de significado en muy poco sintaxis

Simulando el operador ternario 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'

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, se ejecuta exp_1; de lo contrario, se ejecuta exp_2.

Nota :- 0, Ninguno, Falso, lista vacía, cadena vacía 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 vuelve "Verdadera", entonces, se evaluará expresión_1 pero no expresión_2.Si "y" algo con 0 (cero), el resultado siempre será sencillo. Entonces, 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á como cero y no hay necesidad de evaluar la expresión.Así funciona el propio compilador, en todos los idiomas.

En

1 or exp

la expresión exp no será evaluada en absoluto ya que "o" con 1 siempre será 1.Por lo tanto, no será necesario 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 será evaluada ya que True and exp1 sería Verdadero cuando exp1 no sea falso.

De manera similar en

False and exp1 or exp2

La expresión exp1 no será evaluada ya que False equivale a escribir 0 y hacer "y" con 0 sería 0 en sí mismo, pero después de exp1 ya que se usa "o", evaluará la expresión exp2 después de "o".


Nota:- Este tipo de bifurcación usando "o" y "y" solo se puede usar cuando la expresión_1 no tiene un valor de Verdad de False (o 0 o Ninguno o lista vacía [ ] o cadena vacía ''.) ya que si expresión_1 se vuelve False, entonces la expresión_2 será evaluada 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 cuáles sean los valores de verdad de exp_1 y exp_2, haga esto:

[condition] and ([expression_1] or 1) or [expression_2] ;

operador condicional ternario simplemente permite probar una condición en una sola línea de la sustitución de la multilínea si-else haciendo que el compacto código.

Sintaxis:

  

[on_true] si [expresión] más [on_false]

1- Método simple de usar 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 la utilización 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- operador ternario puede ser escrito como anidado si-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")

Por encima de enfoque 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 punta de una respuesta (no es necesario repetir la obvia para la centésima vez), pero a veces lo uso como un acceso directo 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 ceño a él como unpythonic (incluso, :) rubí-ish, pero personalmente encuentro más natural - es decir, cómo se había expresan normalmente, además de un poco más atractiva visualmente en grandes bloques de código.

a if condition else b

Sólo memorizar esta pirámide si tiene problemas para recordar:

     condition
  if           else
a                   b 

SÍ, pitón tiene un operador ternario, aquí es la sintaxis y un código de ejemplo para demostrar el 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")

Muchos lenguajes de programación derivados de C por lo general tienen la siguiente sintaxis del operador condicional ternario:

<condition> ? <expression1> : <expression2>
  

Al principio, el Python B enevolent D ictator F o L ife (I significa Guido van Rossum , por supuesto) lo rechazaron (como el estilo no Pythonic), ya que es muy difícil de entender para las personas que no utilizan para C idioma. Además, el signo de colon : ya tiene muchos usos en Python. Después de PEP 308 fue aprobado, Python finalmente recibió su propio acceso directo de la expresión condicional (lo que usamos ahora):

<expression1> if <condition> else <expression2>

Por lo tanto, en primer lugar se evalúa la condición. Si devuelve True, expresión1 será evaluado para dar el resultado, de lo contrario expresión2 será evaluada. Debido a Lazy Evaluación - mecánica. Sólo una expresión será ejecutado

He aquí algunos ejemplos (condiciones serán evaluadas de izquierda a derecha):

pressure = 10
print('High' if pressure < 20 else 'Critical')

# Result is 'High'

Los operadores ternarios pueden ser encadenados en serie:

pressure = 5
print('Normal' if pressure < 10 else 'High' if pressure < 20 else 'Critical')

# Result is 'Normal'

La siguiente es el mismo que el anterior:

pressure = 5

if pressure < 20:
    if pressure < 10:
        print('Normal')
    else:
        print('High')
else:
    print('Critical')

# Result is 'Normal'

Espero que esto ayude.

Una de las alternativas a la de Python expresión condicional es el siguiente:

{True:"yes", False:"no"}[boolean]

que tiene la siguiente extensión agradable:

{True:"yes", False:"no", None:"maybe"}[boolean_or_none]

La alterativa más corto permanece:

("no", "yes")[boolean]

pero no hay alternativa si se quiere evitar la evaluación de ambos yes() y no() en lo siguiente:

yes() if [condition] else no()

Si se define variable y que desea comprobar si tiene valor sólo se puede 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)

salida voluntad

no Input
no Input
no Input
hello
['Hello']
True

una clara forma de cadena de múltiples operadores:

f = lambda x,y: 'greater' if x > y else 'less' if y > x else 'equal'

array = [(0,0),(0,1),(1,0),(1,1)]

for a in array:
  x, y = a[0], a[1]
  print(f(x,y))

# Output is:
#   equal,
#   less,
#   greater,
#   equal

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top