Se o Python não possui um operador condicional ternário, é possível simular um usando outras construções de linguagem?
python
operators
ternary-operator
conditional-operator
devotados
fonte
fonte
case [...] { when ... then ...} [ else ... ] end
um efeito semelhante, mas nem um pouco ternário.Respostas:
Sim, foi adicionado na versão 2.5. A sintaxe da expressão é:
Primeiro
condition
é avaliado e, em seguida, exatamente um de uma
oub
é avaliado e retornado com base no valor booleano decondition
. Secondition
avalia paraTrue
, entãoa
é avaliado e retornado, masb
é ignorado; caso contrário, quandob
é avaliado e retornado, masa
é ignorado.Isso permite um curto-circuito, porque quando
condition
somente verdadeiroa
é avaliado eb
não é avaliado, mas quandocondition
é falso somenteb
é avaliado ea
não é avaliado.Por exemplo:
Observe que condicionais são uma expressão , não uma declaração . Isso significa que você não pode usar instruções de atribuição
pass
ou outras instruções dentro de uma expressão condicional :No entanto, você pode usar expressões condicionais para atribuir uma variável da seguinte maneira:
Pense na expressão condicional como alternando entre dois valores. É muito útil quando você está em uma situação de "um valor ou outro", mas não faz muito mais.
Se você precisar usar instruções, precisará usar uma
if
instrução normal em vez de uma expressão condicional .Lembre-se de que alguns Pythonistas são desaprovados por vários motivos:
condition ? a : b
operador ternário clássico de muitas outras linguagens (como C, C ++, Go, Perl, Ruby, Java, Javascript, etc.), que podem levar a erros quando pessoas não familiarizadas com o Python " comportamento surpreendente "use-o (eles podem reverter a ordem dos argumentos).if
' possa ser realmente útil e torne seu script mais conciso, ele realmente complica seu código)Se estiver com problemas para lembrar a ordem, lembre-se de que, quando lido em voz alta, você (quase) diz o que quer dizer. Por exemplo,
x = 4 if b > 8 else 9
é lido em voz alta comox will be 4 if b is greater than 8 otherwise 9
.Documentação oficial:
fonte
f(x) = |x| = x if x > 0 else -x
parece muito natural para os matemáticos. Você também pode entendê-lo como fazer A na maioria dos casos, exceto quando C, em seguida, você deve fazer B ...z = 3 + x if x < y else y
. Sex=2
ey=1
, você pode esperar que produza 4, mas na verdade produziria 1.z = 3 + (x if x > y else y)
é o uso correto.z = 3 + x if x < y else 3 + y
) ou agrupar a condicional (z = 3 + (x if x < y else y)
ouz = (x if x < y else y) + 3
)Você pode indexar em uma tupla:
test
precisa retornar Verdadeiro ou Falso .Pode ser mais seguro implementá-lo sempre como:
ou você pode usar o built-in
bool()
para garantir um valor booleano :fonte
(lambda: print("a"), lambda: print("b"))[test==true]()
[]
s pode ser uma expressão arbitrária. Além disso, por segurança, você pode testar explicitamente a veracidade escrevendo[bool(<expression>)]
. Abool()
função existe desde a v2.2.1.True
eFalse
como as chaves:{True:trueValue, False:falseValue}[test]
não sei se isso é menos eficiente, mas evita pelo menos todo debate "elegante" vs. "feio". Não há ambiguidade em lidar com um booleano, e não com um int.Para versões anteriores à 2.5, há o truque:
Pode dar resultados errados quando
on_true
tem um valor booleano falso. 1Embora tenha o benefício de avaliar expressões da esquerda para a direita, o que é mais claro na minha opinião.
1. Existe um equivalente de C? ”:” Operador ternário?
fonte
<expression 1> if <condition> else <expression 2>
fonte
A partir da documentação :
Novo desde a versão 2.5.
fonte
Um operador para uma expressão condicional no Python foi adicionado em 2006 como parte da Proposta de aprimoramento do Python 308 . Sua forma difere do
?:
operador comum e é:que é equivalente a:
Aqui está um exemplo:
Outra sintaxe que pode ser usada (compatível com versões anteriores à 2.5):
onde operandos são avaliados preguiçosamente .
Outra maneira é indexar uma tupla (que não é consistente com o operador condicional da maioria dos outros idiomas):
ou dicionário explicitamente construído:
Outro método (menos confiável), mas mais simples, é usar
and
eor
operadores:no entanto, isso não vai funcionar se
x
seriaFalse
.Uma solução possível é criar
x
ey
listar ou tuplas conforme a seguir:ou:
Se você estiver trabalhando com dicionários, em vez de usar uma condicional ternária, poderá aproveitar
get(key, default)
, por exemplo:Fonte: ?: Em Python na Wikipedia
fonte
result = {1: x, 0: y}[a > b]
é uma outra variante possível (True
eFalse
são números inteiros com valores efectivamente1
e0
)Infelizmente, o
solução não tem comportamento de curto-circuito; portanto, ambos
falseValue
etrueValue
são avaliados independentemente da condição. Isto pode ser sub-tima ou mesmo buggy de (ou seja, tantotrueValue
efalseValue
podem ser métodos e ter efeitos colaterais).Uma solução para isso seria
(execução atrasada até que o vencedor seja conhecido;)), mas introduz inconsistência entre objetos que podem ser chamados e não chamados. Além disso, ele não resolve o caso ao usar propriedades.
E assim continua a história - escolher entre as três soluções mencionadas é uma troca entre ter o recurso de curto-circuito, usar pelo menos o Зython 2.5 (IMHO não é mais um problema) e não estar propenso a erros "
trueValue
-valoriza-para-falso" .fonte
if else if
.Operador ternário em diferentes linguagens de programação
Aqui, apenas tento mostrar alguma diferença importante
ternary operator
entre algumas linguagens de programação.fonte
Para o Python 2.5 e mais recente, há uma sintaxe específica:
Nos Pythons mais antigos, um operador ternário não é implementado, mas é possível simulá-lo.
No entanto, existe um problema em potencial que, se
cond
avaliadoTrue
eon_true
avaliadoFalse
,on_false
é retornado em vez deon_true
. Se você deseja esse comportamento, o método está OK, caso contrário, use o seguinte:que pode ser envolvido por:
e usado desta maneira:
É compatível com todas as versões do Python.
fonte
q("blob", on_true, on_false)
retornaon_false
, enquantoon_true if cond else on_false
retornaon_true
. A solução é substituircond
comcond is not None
nestes casos, apesar de que não é uma solução perfeita.bool(cond)
vez decond is True
? O primeiro verifica a veracidade decond
, o último verifica a igualdade de ponteiros com oTrue
objeto. Como destacado por @AndrewCecil,"blob"
é verdade, mas éis not True
.[on_false, on_True][cond is True]
para que a expressão fique mais curta.Você pode encontrar frequentemente
mas isso leva a um problema quando on_true == 0
onde você esperaria de um operador ternário normal esse resultado
fonte
Sim. No arquivo de gramática :
A parte de interesse é:
Portanto, uma operação condicional ternária é da forma:
expression3
será avaliado preguiçosamente (ou seja, avaliado apenas seexpression2
for falso em um contexto booleano). E por causa da definição recursiva, você pode encadear indefinidamente (embora possa ser considerado um estilo ruim).Uma observação sobre o uso:
Observe que todos
if
devem ser seguidos com umelse
. As pessoas que aprendem a compreensão da lista e as expressões geradoras podem achar que essa é uma lição difícil de aprender - o seguinte não funcionará, pois o Python espera uma terceira expressão para outra pessoa:o que gera a
SyntaxError: invalid syntax
. Portanto, o exposto acima é uma parte incompleta da lógica (talvez o usuário espere um não operacional na condição falsa) ou o que pode ser pretendido é usar o expression2 como um filtro - observa que o seguinte é Python legal:expression2
funciona como um filtro para a compreensão da lista e não é um operador condicional ternário.Sintaxe alternativa para um caso mais restrito:
Você pode achar um pouco doloroso escrever o seguinte:
expression1
terá que ser avaliado duas vezes com o uso acima. Pode limitar a redundância se for simplesmente uma variável local. No entanto, um idioma pitonico comum e com bom desempenho para este caso de uso é usaror
o comportamento de atalho:o que é equivalente em semântica. Observe que alguns guias de estilo podem limitar esse uso com base na clareza - ele inclui muito significado em muito pouca sintaxe.
fonte
expression1 or expression2
sendo semelhante e com os mesmos inconvenientes / positivos queexpression1 || expression2
em javascriptexpressionN
para todas as instâncias seja consistente, pode ser mais fácil entender com nomes que distinguem a expressão de teste condicional das duas expressões de resultado; por exemploresult1 if condition else result2
,. Isso é especialmente evidente ao aninhar (também conhecido como encadeamento):result1 if condition1 else result2 if condition2 else result3
. Vê quanto melhor isso é lido dessa maneira?Simulando o operador ternário python.
Por exemplo
resultado:
fonte
result = (y, x)[a < b]
Por que você usa alambda
função ?O operador condicional ternário simplesmente permite testar uma condição em uma única linha, substituindo a multilinha, caso contrário, tornando o código compacto.
Sintaxe:
1- Método simples de usar operador ternário:
2- Método direto de usar tuplas, dicionário e lambda:
3- O operador ternário pode ser escrito como aninhado if-else:
A abordagem acima pode ser escrita como:
fonte
if-else
não é realmente uma reescrita do operador ternário e produzirá uma saída diferente para os valores selecionados de aeb (especificamente se um for um tipo que implementa um__ne__
método estranho ).você consegue fazer isso :-
[condition] and [expression_1] or [expression_2] ;
Exemplo:-
print(number%2 and "odd" or "even")
Isso imprimiria "ímpar" se o número for ímpar ou "par" se o número for par.
O resultado: - Se a condição for verdadeira, exp_1 é executado e exp_2 é executado.
Nota :- 0, Nenhum, Falso, lista vazia, emptyString é avaliado como Falso. E qualquer dado diferente de 0 é avaliado como True.
Veja como funciona:
se a condição [condição] se tornar "Verdadeira", a expressão_1 será avaliada, mas não a expressão_2. Se "e" algo com 0 (zero), o resultado será sempre rápido. Portanto, na instrução abaixo,
A expressão exp não será avaliada, pois "e" com 0 sempre será avaliado como zero e não há necessidade de avaliar a expressão. É assim que o próprio compilador funciona, em todos os idiomas.
No
a expressão exp não será avaliada, pois "ou" com 1 sempre será 1. Portanto, não será necessário avaliar a expressão exp, pois o resultado será 1 de qualquer maneira. (métodos de otimização do compilador).
Mas no caso de
A segunda expressão exp2 não será avaliada desde
True and exp1
seria True quando exp1 não for falsa.Da mesma forma em
A expressão exp1 não será avaliada, pois False equivale a escrever 0 e fazer "e" com 0 seria 0 em si, mas após exp1, uma vez que "ou" é usado, ele avaliará a expressão exp2 após "ou".
Nota:- Esse tipo de ramificação usando "ou" e "e" só pode ser usado quando a expressão_1 não tiver um valor de Verdadeiro Falso (ou 0 ou Nenhum ou lista vazia [] ou cadeia de caracteres vazia ''.), Pois se expressão_1 se tornar False, a expressão_2 será avaliada devido à presença "ou" entre exp_1 e exp_2.
Caso você ainda deseje fazê-lo funcionar em todos os casos, independentemente dos valores verdadeiros exp_1 e exp_2, faça o seguinte: -
[condition] and ([expression_1] or 1) or [expression_2] ;
fonte
x = [condition] and ([expression_1] or 1) or [expression_2]
eexpression_1
avalia como falso,x
será1
, nãoexpression_1
. Use a resposta aceita.Mais uma dica do que uma resposta (não é necessário repetir o óbvio pelo tempo hundreth), mas às vezes eu o uso como um atalho oneliner em tais construções:
, torna-se:
Alguns (muitos :) podem parecer desonestos (até mesmo, rubi-ish :), mas pessoalmente acho mais natural - ou seja, como você o expressaria normalmente, além de um pouco mais atraente visualmente em grandes blocos de código.
fonte
print( 'yes' if conditionX else 'nah' )
a sua resposta. :-)print()
nos dois casos - e parece um pouco mais pitônico, devo admitir :) Mas e se as expressões / funções não forem as mesmas - comoprint('yes') if conditionX else True
- para obter oprint()
único na verdadeconditionX
print('yes') if conditionX else print('nah')
é que ele fornece um SyntaxError no Python2.print "yes"
enquanto no Python 3 é uma função -print("yes")
. Isso pode ser resolvido usando-o como uma declaração ou melhor -from future import print_function
.Apenas memorize esta pirâmide se tiver problemas para lembrar:
fonte
Uma das alternativas à expressão condicional do Python
é o seguinte:
que tem a seguinte boa extensão:
A alternativa mais curta permanece:
mas não há alternativa para
se você deseja evitar a avaliação de
yes()
eno()
, porque emambos
no()
eyes()
são avaliados.fonte
Muitas linguagens de programação derivadas
C
geralmente têm a seguinte sintaxe de operador condicional ternário:Então, primeiro ele avalia a condição. Se retornar
True
, a expressão1 será avaliada para fornecer o resultado, caso contrário, a expressão2 será avaliada. Devido à mecânica da Lazy Evaluation - apenas uma expressão será executada.Aqui estão alguns exemplos (as condições serão avaliadas da esquerda para a direita):
Os operadores ternários podem ser encadeados em série:
O seguinte é o mesmo que o anterior:
Espero que isto ajude.
fonte
Como já respondi, sim, existe um operador ternário em python:
Informação adicional:
Se
<expression 1>
é a condição, você pode usar a avaliação de curto-circuito :PS: Obviamente, uma avaliação de curto-circuito não é um operador ternário, mas geralmente o ternário é usado nos casos em que o curto-circuito seria suficiente.
fonte
short-circuit
avaliação.SIM, python tem um operador ternário, aqui está a sintaxe e um código de exemplo para demonstrar o mesmo :)
fonte
print
realmente não é uma boa escolha, pois isso dará um SyntaxError no Python2.Python tem uma forma ternária para atribuições; no entanto, pode haver uma forma ainda mais curta da qual as pessoas devem estar cientes.
É muito comum precisar atribuir a uma variável um valor ou outro, dependendo de uma condição.
^ Essa é a forma longa para realizar essas tarefas.
Abaixo está a forma ternária. Mas essa não é a maneira mais sucinta - veja o último exemplo.
Com o Python, você pode simplesmente usar
or
para atribuições alternativas.O acima funciona desde que
li1
éNone
e o interp trata isso como False em expressões lógicas. A interp então avança e avalia a segunda expressão, que não éNone
e não é uma lista vazia - portanto, é atribuída a a.Isso também funciona com listas vazias. Por exemplo, se você deseja atribuir a
a
lista que tiver itens.Sabendo disso, você pode simplesmente executar tais tarefas sempre que as encontrar. Isso também funciona com strings e outros iterables. Você pode atribuir a
a
sequência que não estiver vazia.Eu sempre gostei da sintaxe secundária, mas o Python dá um passo adiante!
Eu entendo que alguns podem dizer que essa não é uma boa escolha estilística, pois depende de mecânicas que não são imediatamente aparentes para todos os desenvolvedores. Pessoalmente, não concordo com esse ponto de vista. Python é uma linguagem rica em sintaxe, com muitos truques idiomáticos que não são imediatamente aparentes para o dabler. Mas quanto mais você aprende e entende a mecânica do sistema subjacente, mais você o aprecia.
fonte
Outras respostas falam corretamente sobre o operador ternário do Python. Eu gostaria de complementar mencionando um cenário para o qual o operador ternário é frequentemente usado, mas para o qual existe uma linguagem melhor. Este é o cenário do uso de um valor padrão.
Suponha que desejemos usar
option_value
com um valor padrão, se não estiver definido:ou simplesmente
No entanto, uma solução cada vez melhor é simplesmente escrever
fonte
se a variável estiver definida e você quiser verificar se ela possui valor, basta
a or b
irá produzir
fonte
x if x else y
, mas nãox if z else y
.Uma maneira elegante de encadear vários operadores:
fonte
Eu acho difícil a sintaxe padrão do python
val = a if cond else b
, às vezes faço isso:Claro, ele tem a desvantagem de sempre avaliar os dois lados (aeb), mas a sintaxe é muito mais clara para mim
fonte
val = a if cond else b
declaração mais simples .**
**
fonte