Pergunta

Se Python não tem um operador condicional ternário, é possível simular um usando outras construções de linguagem?

Foi útil?

Solução

Sim, era acrescentou na versão 2.5. A sintaxe da expressão é:

a if condition else b
é avaliada

Primeiro condition, então exatamente um dos dois a ou b é avaliado e devolvido com base na valor booleano de condition. Se avalia condition para True, então a é avaliado e devolvido mas b é ignorado, ou então quando b é avaliado e devolvido mas a é ignorado.

Isso permite que um curto-circuito, porque quando condition é verdade apenas a é avaliado e b não é avaliada em tudo, mas quando condition é falso única b é avaliado e a não é avaliada em tudo.

Por exemplo:

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

Note que condicionais são uma expressão , e não um declaração . Isto significa que você não pode usar comandos de atribuição ou pass ou outros declarações dentro de uma condicional expressão :

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

Você pode, entretanto, usar expressões condicionais para atribuir uma variável como assim:

x = a if True else b

Pense na expressão condicional como alternar entre dois valores. É muito útil quando você está em um 'um valor ou outra' situação, mas não fazer muito mais.

Se você precisa usar declarações, você tem que usar um if normal de declaração em vez de uma condicional expressão .


Tenha em mente que ele é desaprovado por alguns Pythonistas por várias razões:

  • A ordem dos argumentos é diferente daqueles do operador condition ? a : b ternário clássico de muitas outras linguagens (como C, C ++, Go, Perl, Ruby, Java, Javascript, etc.), o que pode levar a erros quando as pessoas familiarizado com o uso de comportamento de Python "surpreendente" que (eles podem inverter a ordem argumento).
  • Alguns acham que é "pesado", uma vez que vai ao contrário do fluxo normal do pensamento (pensamento da condição em primeiro lugar e, em seguida, os efeitos).
  • razões estilísticas. (Embora o 'if inline' pode ser realmente útil, e fazer o seu roteiro mais conciso, ele realmente faz complicar o seu código)

Se você está tendo problemas para lembrar a ordem, então lembre-se que, quando lido em voz alta, você (quase) dizer o que você quer dizer. Por exemplo, x = 4 if b > 8 else 9 é lido em voz alta como x will be 4 if b is greater than 8 otherwise 9.

A documentação oficial:

Outras dicas

Você pode indexar em uma tupla:

(falseValue, trueValue)[test]

necessidades test para retornar true ou false .
Ele pode ser mais seguro para implementá-lo sempre como:

(falseValue, trueValue)[test == True]

ou você pode usar o built-in bool() para garantir um valor booleano :

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

Para versões anteriores ao 2.5, não é o truque:

[expression] and [on_true] or [on_false]

Pode dar resultados errados quando on_true tem um valor booleano falso. 1
Apesar de não ter o benefício de avaliar expressões esquerda para a direita, o que é mais claro na minha opinião.

1. Existe um equivalente de da C? “:” operador ternário

?

<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

A partir a documentação :

As expressões condicionais (às vezes chamado de “operador ternário”) tem a prioridade mais baixa de todas as operações Python.

O x if C else y expressão primeiro avalia a condição, C ( não x ); se C é verdade, x é avaliado e seu valor é retornado; caso contrário, y é avaliado e seu valor é retornado.

PEP 308 para mais detalhes sobre expressões condicionais.

Novo desde a versão 2.5.

Um operador de uma expressão condicional em Python foi adicionado em 2006 como parte de Python Enhancement proposta 308 . Sua forma varia de operador ?: comum e que é:

<expression1> if <condition> else <expression2>

o que equivale a:

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

Aqui está um exemplo:

result = x if a > b else y

Outra sintaxe que pode ser utilizado (compatível com versões antes 2.5):

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

onde operandos são preguiçosamente Avaliados .

Outra maneira é por indexar uma tupla (que não é consistente com o operador condicional da maioria das outras línguas):

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

ou dicionário explicitamente construídos:

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

Outro (menos confiável), mas o método mais simples é usar operadores and e or:

result = (a > b) and x or y

No entanto isto não vai funcionar se x seria False.

Uma solução possível é fazer listas x e y ou tuplas como no seguinte:

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

ou

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

Se você está trabalhando com dicionários, em vez de usar um ternário condicional, você pode tirar vantagem de get(key, default) , por exemplo:

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

Fonte: :? Em Python na Wikipedia

Infelizmente, a

(falseValue, trueValue)[test]

solução não tem comportamento de curto-circuito; assim, tanto falseValue e trueValue são avaliados independentemente da condição. Isto pode ser sub-tima ou mesmo buggy de (isto é, tanto trueValue e falseValue poderia haver métodos e têm efeitos secundários).

Uma solução para isso seria

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

(execução adiada até que o vencedor é conhecido;)), mas introduz inconsistência entre objetos que podem ser chamadas e não pode ser chamado. Além disso, ele não resolve o caso quando se usa propriedades.

E assim a história continua - a escolha entre 3 soluções mencionadas é um trade-off entre ter o recurso de curto-circuito, usando pelo menos ?ython 2,5 (IMHO não mais um problema) e não estar propenso a "trueValue Avalia-to -false" erros.

Operador Ternário em diferentes linguagens de programação

Aqui eu apenas tentar mostrar alguma diferença importante em ternary operator entre um par de linguagens de programação.

Operador Ternário em Javascript

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

Operador Ternário em Ruby

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

operador ternário em Scala

val a = true ? 1 | 0
# 1
val b = false ? 1 | 0
# 0

operador ternário na programação R

a <- if (TRUE) 1 else 0
# 1
b <- if (FALSE) 1 else 0
# 0

operador ternário em Python

a = 1 if True else 0
# 1
b = 1 if False else 0
# 0

Para Python 2.5 e mais recentes, há uma sintaxe específica:

[on_true] if [cond] else [on_false]

Em Pythons mais velhos um operador ternário não está implementada, mas é possível simular isso.

cond and on_true or on_false

No entanto, há um problema potencial, o que se avalia cond para True e on_true avalia a False então on_false é devolvido em vez de on_true. Se você quiser este comportamento do método é OK, caso contrário, use o seguinte:

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

que pode ser enrolado por:

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

e usado desta maneira:

q(cond, on_true, on_false)

É compatível com todas as versões do Python.

Você pode encontrar muitas vezes

cond and on_true or on_false

mas isso levar a problemas quando on_true == 0

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

onde você poderia esperar de um operador ternário normal, este resultado

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

O Python tem um operador condicional ternário?

Sim. Do gramática arquivo :

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

A parte de interesse é:

or_test ['if' or_test 'else' test]

Assim, uma operação condicional ternário é da forma:

expression1 if expression2 else expression3

expression3 será preguiçosamente avaliadas (ou seja, avaliada somente se expression2 é falso em um contexto booleano). E por causa da definição recursiva, você pode encadear-los indefinidamente (embora possa considerada um estilo ruim.)

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

Uma nota sobre o uso:

Note que cada if devem ser seguidas com um else. Pessoas aprendendo compreensões de lista e gerador de expressões pode achar que isso seja uma lição difícil de aprender - a seguir não vai funcionar, como Python espera uma terceira expressão de uma coisa:

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

que levanta uma SyntaxError: invalid syntax. Assim, o acima é tanto uma peça incompleta da lógica (talvez o usuário espera um não-op na falsa condição) ou o que pode ser destinada é usar expressão2 como um filtro - notas que o seguinte é Python legal:

[expression1 for element in iterable if expression2]

expression2 funciona como um filtro para a compreensão da lista, e é não um ternário condicional operador.

Sintaxe alternativa para um caso mais estreita:

Você pode achar que é um pouco doloroso para escrever o seguinte:

expression1 if expression1 else expression2

expression1 terão de ser avaliados duas vezes com o uso acima. Pode limitar a redundância se é simplesmente uma variável local. No entanto, uma comum e performance Pythonic idioma para este caso de uso é um comportamento shortcutting uso de or:

expression1 or expression2

que é equivalente em semântica. Note-se que algumas estilo-guias podem limitar esse uso por razões de clareza -. Ele embalar um monte de significado em muito pouco sintaxe

Simulando o operador python ternário.

Por exemplo

a, b, x, y = 1, 2, 'a greather than b', 'b greater than a'
result = (lambda:y, lambda:x)[a > b]()

saída:

'b greater than a'

Você pode fazer isso: -

[condition] and [expression_1] or [expression_2] ;

Exemplo: -

print(number%2 and "odd" or "even")

Isto imprimir "estranho" se o número for ímpar ou "até mesmo" se o número é ainda.


O resultado: -. Se a condição for verdadeira exp_1 é executado exp_2 outra coisa é executado

Nota: - 0, None, False, emptylist, avalia emptyString como False. E quaisquer outros que 0 avalia os dados para True.

Veja como funciona:

Se a condição [condição] torna-se "True", em seguida, expressão_1 serão avaliados, mas não expressão_2. Se nós "e" algo com 0 (zero), o resultado será sempre a ser fasle .Assim no abaixo declaração,

0 and exp

O exp expressão não serão avaliadas em tudo desde "e" com 0 irá sempre avaliar a zero e não há necessidade de se avaliar a expressão. Isto é como o compilador em si funciona, em todas as línguas.

Em

1 or exp

o exp expressão não serão avaliadas em tudo desde "ou" com 1 será sempre 1. Portanto, não vai se preocupar em avaliar o exp expressão desde o resultado será 1 de qualquer maneira. (métodos de optimização compilador).

Mas no caso de

True and exp1 or exp2

O segundo exp2 expressão não será avaliada desde True and exp1 seria True quando exp1 não é falsa.

Da mesma forma, em

False and exp1 or exp2

O exp1 expressão não serão avaliadas desde Falso é equivalente a escrever 0 e fazendo "e" com 0 seria 0 em si mas depois exp1 desde "ou" é usado, ele irá avaliar a exp2 expressão depois de "ou".


Nota: - Este tipo de ramificação usando "ou" e "e" só pode ser usado quando o expressão_1 não tem um valor de verdade de Falso (ou 0 ou Nenhum ou emptylist [] ou emptystring ''.), pois se expressão_1 se torna falsa, então o expressão_2 será avaliada por causa da presença "ou" entre exp_1 e exp_2.

No caso de você ainda quer fazer o trabalho para todos os casos, independentemente do que exp_1 e valores exp_2 verdade são, faça o seguinte: -

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

ternário condicional operador simplesmente permite testar uma condição em uma única linha substituindo a várias linhas if-else fazendo o compacto código.

Sintaxe:

[on_true] se [expressão] outra [on_false]

1- Método Simples de usar ternário operador:

# 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 Direto de usar tuplas, dicionário, e 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 ternário operador pode ser escrita como nested 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")

abordagem acima pode ser escrita 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

Mais uma dica do que uma resposta (não precisa repetir o óbvio para o tempo hundreth), mas às vezes eu usá-lo como um atalho oneliner em tais construções:

if conditionX:
    print('yes')
else:
    print('nah')

, torna-se:

print('yes') if conditionX else print('nah')

Alguns (muitos :) podem desaprovam lo como unpythonic (mesmo, rubi-ish :), mas eu pessoalmente encontrá-lo mais natural - ou seja, como você expressá-lo normalmente, além de um pouco mais visualmente atraente em grandes blocos de código.

a if condition else b

Apenas memorize esta pirâmide se você tem lembrança problemas:

     condition
  if           else
a                   b 

SIM, pitão ter um operador ternário, aqui, é a sintaxe e um código de exemplo para demonstrar a mesma:)

#[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")

Muitas linguagens de programação derivadas de C geralmente têm a seguinte sintaxe de ternário operador condicional:

<condition> ? <expression1> : <expression2>

Na primeira, o Python B enevolent D ictator F ou G ife (I significa Guido van Rossum , é claro) rejeitaram (estilo como não Pythonic), já que é muito difícil de entender para as pessoas não costumavam linguagem C. Além disso, o sinal de cólon : já tem muitos usos na Python. Depois de PEP 308 foi aprovada, Python finalmente recebeu o seu próprio atalho expressão condicional (o que usamos agora):

<expression1> if <condition> else <expression2>

Assim, em primeiro lugar avalia a condição. Se ela retorna True, expressão1 será avaliado para dar o resultado, caso contrário expressão2 será avaliado. Devido à preguiçoso Avaliação mecânica -. Apenas uma expressão será executada

Aqui estão alguns exemplos (condições serão avaliadas da esquerda para a direita):

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

# Result is 'High'

operadores ternários podem ser encadeados em série:

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

# Result is 'Normal'

O seguinte é a mesma que a anterior:

pressure = 5

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

# Result is 'Normal'

Espero que isso ajude.

Uma das alternativas para Python do condicional expressão é o seguinte:

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

que tem a seguinte extensão agradável:

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

Os menores restos alterative:

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

mas não há alternativa se você quer evitar a avaliação de ambos yes() e no() no seguinte:

yes() if [condition] else no()

Se variável é definida e você quer verificar se ele tem valor você pode apenas 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)

saída vontade

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

Uma maneira elegante de operadores de vários cadeia:

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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top