Python >> Tutoriel Python >  >> Python

Python une ligne ternaire

L'opérateur ternaire le plus basique x if c else y se compose de trois opérandes x , c , et y . C'est une expression avec une valeur de retour. L'opérateur ternaire renvoie x si l'expression booléenne c évalue à True . Sinon, si l'expression c évalue à False , l'opérateur ternaire renvoie l'alternative y .

Ternaire (du latin ternarius ) est un adjectif signifiant "composé de trois éléments" . (source) Ainsi, littéralement, l'opérateur ternaire en Python est composé de trois opérandes. Dans de nombreux cercles Python, l'opérateur ternaire est également appelé "expression conditionnelle" car il n'exécute une expression donnée que si une condition est remplie.

Syntaxe :Les trois opérandes sont écrits sous la forme x if c else y qui se lit comme "retour x si c sinon renvoie y “. Écrivons cela plus intuitivement comme :

<OnTrue> if <Condition> else <OnFalse>
Opérande Description
L'expression de retour de l'opérateur dans le cas où la condition est évaluée à True
<État> La condition qui détermine s'il faut retourner la branche ou .
L'expression de retour de l'opérateur si la condition est évaluée à False

Examinons un exemple minimal dans notre shell de code interactif :

Exercice :Exécutez le code et entrez votre âge. Quelle est la sortie ? Exécutez à nouveau le code et essayez de modifier la sortie !

Plongeons-nous dans les différentes variantes de l'opérateur Ternaire en Python !

Exemples ternaires Python

Passons rapidement en revue quelques exemples sur différentes méthodes d'utilisation de l'opérateur ternaire :

age = 17

# Method 1: Basic Ternary
print('wtf' if age<20 else 'What?')
'wtf'

# Method 2: Ternary Tuple
# (onFalse, onTrue) [condition]
print(('wtf', 'What?')[age<20])
'What?'

# Method 3: Ternary Dictionary
# Use Dictionary True/False values
print({True: 'wtf', False: 'What?'}[age<20])
'wtf'

# Method 4: Ternary Lambda
# Lambda function with 0 arguments
# Execute only one branch expression --> more efficient
print((lambda: 'wtf', lambda:'What?')[age<20]())
'What?'

Certains d'entre eux sont assez déroutants, n'est-ce pas? Restez avec moi un instant car vous en apprendrez plus sur chacun de ces prochains ! 🙂

Ternaire de base

L'opérateur ternaire le plus basique x if c else y se compose de trois opérandes x , c , et y . C'est une expression avec une valeur de retour.

  • L'opérateur ternaire renvoie x si l'expression booléenne c évalue à True .
  • Sinon, si l'expression c évalue à False , l'opérateur ternaire renvoie l'alternative y .

Cela vous permet d'attribuer des valeurs à une variable de manière conditionnelle à l'aide de l'opérateur ternaire. Vous pouvez également imprimer des valeurs de manière conditionnelle en passant un opérateur ternaire de base dans le print() fonction :

age = 17
print('wtf' if age<20 else 'What?')
'wtf'

La condition c=age<20 évalue à True . Ainsi, la première partie de l'opérateur ternaire x='wtf' est renvoyé et passé dans le print() déclaration. En revanche, les personnes de plus de 20 ans auraient tendance à demander 'What?' plutôt que 'wtf' ce serait donc la sortie de l'opérateur ternaire.

Tuple ternaire Python

Une forme abrégée de l'opérateur ternaire est la syntaxe de tuple suivante .

Syntaxe :Vous pouvez utiliser la syntaxe de tuple (x, y)[c] composé d'un tuple (x, y) et une condition c entre crochets. Voici une manière plus intuitive de représenter cette syntaxe de tuple.

(<OnFalse>, <OnTrue>)[<Condition>]
Opérande Description
L'expression de retour de l'opérateur si la condition est évaluée à True
<État> La condition qui détermine s'il faut retourner la branche ou .
L'expression de retour de l'opérateur si la condition est évaluée à False

En fait, l'ordre du <OnFalse> et <OnTrue> opérandes est simplement inversé par rapport à l'opérateur ternaire de base. Tout d'abord, vous avez la branche qui est renvoyée si la condition ne tient PAS. Deuxièmement, vous exécutez la branche renvoyée si la condition est vérifiée.

age = 17
print(('wtf', 'What?')[age<20])
'What?'

La condition age<20 détient donc la valeur de retour passée dans le print() la fonction est le <OnTrue> succursale 'What?' . Ne vous inquiétez pas si cela vous embrouille, vous n'êtes pas seul. Clarifions pourquoi cette syntaxe de tuple fonctionne comme elle le fait !

Tout d'abord, vous créez un tuple ('wtf', 'What?') . Pour accéder à la première valeur de tuple 'wtf' , vous utiliseriez la syntaxe d'indexation standard ('wtf', 'What?')[0] . Pour accéder à la deuxième valeur de tuple 'What?' , vous utiliseriez la syntaxe d'indexation standard ('wtf', 'What?')[1] .

Deuxièmement, vous créez une condition age<20 . Vous utilisez cette condition comme valeur d'indexation. Vous vous retrouvez avec soit ('wtf', 'What?')[False] ou ('wtf', 'What?')[True] . Comme vous le savez peut-être, les booléens False et True sont représentés par des entiers 0 et 1 en Python. Ainsi, vous obtenez ('wtf', 'What?')[0] et ('wtf', 'What?')[1] , respectivement.

En d'autres termes  :si votre condition est évaluée à False , vous accédez à la première valeur de tuple. Si votre état est évalué à True , vous accédez à la deuxième valeur de tuple.

Dictionnaire ternaire Python

Problème :Étant donné un dictionnaire et une clé. Pouvez-vous utiliser l'opérateur ternaire pour renvoyer la clé du dictionnaire, mais uniquement si elle existe pour éviter l'erreur de clé ? Si la clé n'existe pas, une fonction "de secours" doit être exécutée.

Exemple  :Supposons que vous vouliez faire quelque chose comme ce qui suit (pseudocode) :

var = dict["key"] if dict.has_key("key") else "fallback"

Solution :Vous pouvez utiliser l'opérateur ternaire dict[key] if key in dict else "fallback" pour y parvenir :

d = {'Alice': 17, 'Bob': 22}
key = 'Alice'

# Has key:
var = d[key] if key in d else -1
print(var)
# 17

# Doesn't have key:
key = 'Ann'
var = d[key] if key in d else -1
print(var)
# -1

L'opérateur ternaire renvoie la valeur associée à la clé donnée, mais uniquement si la clé existe. S'il n'existe pas, il renvoie la valeur par défaut -1.

Cependant, une manière plus Pythonic d'accomplir la même chose d'une manière plus lisible et plus concise est d'utiliser le dictionary.get(key, default) fonction :

d = {'Alice': 17, 'Bob': 22}
key = 'Alice'

# Has key:
var = d.get(key, -1)
print(var)
# 17

# Doesn't have key:
key = 'Ann'
var = d.get(key, -1)
print(var)
# -1

La structure externe du code est la même, mais la fonction get avec la valeur par défaut -1 remplace sémantiquement l'opérateur ternaire plus compliqué.

Python Ternaire Lambda

Vous pouvez également écrire des instructions conditionnelles dans une fonction lambda. Souvent, cela se traduit par une manière plus concise et plus lisible d'accomplir la même chose. Supposons que vous ayez l'exemple suivant :

def f(x):
    if x > 100:
        x = 1.1*x
    else:
        x = 1.05*x
    return x


print(f(100))
# 105.0

La fonction f(x) prend un argument x et l'augmente de 10 % si l'argument est supérieur à 100. Sinon, il l'augmente de 5 %. Il s'avère que vous pouvez également utiliser efficacement l'opérateur ternaire :

f = lambda x: 1.1*x if x>100 else 1.05*x

print(f(100))
# 105.0

Le résultat est le même. Un codeur Python intermédiaire à avancé n'aura aucun problème à comprendre le code et il est beaucoup plus concis. C'est pourquoi je préférerais cette méthode à la première.

Lignes multiples ternaires en Python

Et si vous avez un opérateur ternaire très long ?

var = 'I want to learn Python' if 42**2<166 else 'I want to learn Go programming'
print(var)
# I want to learn Go programming

Problème :Comment écrire l'opérateur ternaire sur plusieurs lignes ?

Solution  :Vous pouvez étendre n'importe quelle ligne logique en Python sur plusieurs lignes physiques en utilisant la parenthèse.

var = 'I want to learn Python' if 42**2<166 else 'I want to learn Go programming'
print(var)

var = ('I want to learn Python'
       if 42**2<166 else
       'I want to learn Go programming')
print(var)
# I want to learn Go programming

Il s'agit de la manière standard PEP8 de couper les longues lignes, si vous ne pouvez pas le faire de manière plus naturelle (comme en évitant l'opérateur ternaire et en utilisant l'instruction if dans cet exemple).

Python Ternaire Elif

À présent, vous avez appris à écrire l'instruction if-else dans une seule ligne de code à l'aide de l'opérateur ternaire. Mais pouvez-vous faire la même chose avec une instruction elif si vous avez plusieurs conditions ?

Bien sûr vous pouvez! (Si vous ne savez pas si vous pouvez faire XYZ dans une seule ligne de Python, supposez simplement que vous le pouvez. Consultez mon nouveau livre "Python One-Liners" pour maîtriser la seule ligne de code !)

Supposons que vous souhaitiez écrire la condition if-then-else suivante dans une seule ligne de code :

>>> x = 42
>>> if x > 42:
>>>     print("no")
>>> elif x == 42:
>>>     print("yes")
>>> else:
>>>     print("maybe")
yes

La branche elif gagne :vous imprimez la sortie "yes" à la coquille. Mais comment le faire en une seule ligne de code ? Utilisez simplement l'opérateur ternaire avec une instruction elif qui ne fonctionnera pas (cela générera une erreur de syntaxe).

La réponse est simple :imbriquer deux opérateurs ternaires comme ceci :

>>> print("no") if x > 42 else print("yes") if x == 42 else print("maybe")
yes

Si la valeur x est supérieure à 42, nous imprimons "non" au shell. Sinon, nous exécutons le reste du code (qui est un opérateur ternaire en soi). Si la valeur x est égale à 42, on imprime "oui", sinon "peut-être".

Ainsi, en imbriquant plusieurs opérateurs ternaires, nous pouvons considérablement augmenter la puissance de notre Python one-liner !

Essayez vous-même :

Exercice :Quelle méthode est la plus concise ? Comptez le nombre de caractères (ou écrivez un petit script qui le fera pour vous;)) !

Article connexe :Python Ternaire Elif

Python ternaire imbriqué

Dans l'exemple précédent, vous avez vu comment un opérateur ternaire imbriqué ajoute sémantiquement une branche elif. En théorie, vous pouvez ajouter un nombre arbitraire de branches elif en imbriquant de plus en plus d'opérateurs ternaires :

# Method 1: If ... Elif ... Else
x = 42
if x > 42:
    y = 1
elif x == 42:
    y = 2
elif x == 12:
    y = 3
else:
    y = 4
print(y)
# 2

# Method 2: Nested Ternary Operator
y = 1 if x > 42 else 2 if x == 42 else 3 if x == 12 else 4
print(y)
# 2

Cependant, la lisibilité en souffre beaucoup et vous ne devriez rien faire de la sorte. Un simple multi-ligne if ... elif ... elif ... else l'énoncé c'est mieux !

Ordre d'évaluation ternaire Python

Problème :Soit un opérateur ternaire X if C else Y qui renvoie l'expression X si état C est remplie et renvoie l'expression Y Par ailleurs. Quel est l'ordre d'évaluation de ces expressions ? Expression Will X évaluer même si la condition C est False ?

Solution :D'après la documentation officielle de Python :"L'expression x if C else y évalue d'abord la condition, C plutôt que x. Si C est vrai, x est évalué et sa valeur est renvoyée; sinon, y est évalué et sa valeur est renvoyée.”

Ainsi, seule la condition correspondante est évaluée, comme on peut le voir dans l'exemple de code suivant :

print('X') if 5>3 else print('Y')
# X

Vous exécutez l'expression print('X') si la condition 5>3 évalue à True (ce qu'il fait). L'observation intéressante est que l'expression print('Y') n'est pas exécuté !

Ternaire Python en compréhension de liste

Vous pouvez utiliser l'opérateur ternaire comme partie expression d'une instruction de compréhension de liste. Récapitulons rapidement les compréhensions de la liste :

Au lieu d'utiliser une expression unaire, vous pouvez utiliser une expression ternaire :

print([x**2 if x%2 else x for x in range(5)])
# [0, 1, 2, 9, 4]

Vous utilisez l'opération ternaire x**2 if x%2 else x pour renvoyer le nombre carré uniquement pour les valeurs impaires. Même les valeurs restent inchangées.

Python Ternaire Pep8 Pythonique

L'opérateur ternaire Python est-il bon ou mauvais ?

L'opérateur ternaire est bon et de style Pythonic qui satisfait la norme PEP8. Certaines règles tacites sont :

  • La branche if doit être la plus probable.
  • N'utilisez pas d'opérateurs ternaires imbriqués (utilisez le if ... elif ... then ... multiligne simple déclarations à la place).
  • N'utilisez pas d'opérateurs ternaires longs avec des expressions compliquées (utilisez à nouveau plusieurs lignes if déclarations à la place).

Python Ternary ne peut pas être attribué à une expression conditionnelle

Si vous utilisez l'opérateur ternaire dans le mauvais sens, il lancera une SyntaxError :

Vous pouvez résoudre l'erreur SyntaxError:can't assign to conditional expression en évitant d'utiliser une instruction d'affectation dans votre opérateur ternaire. Affectez plutôt la valeur de retour de l'opérateur ternaire à une variable si vous devez :

a = 2 if 5>2 else 4
print(a)
# 2

Maintenant, le code ne génère plus d'erreur.

Ternaire Python Aucun

Vous pouvez utiliser n'importe quelle valeur de retour dans l'opérateur ternaire, même None. Par exemple, vous verrez souvent des opérateurs ternaires qui ne renvoient rien et qui exécutent simplement une certaine fonction sans valeur de retour :

age = 20

# Ternary operator returns None
print('hi') if age<20 else print('hello')
# hello

Bien sûr, ce n'est pas un code Python très propre et lisible. Une meilleure alternative serait d'utiliser une simple instruction if :

# Better alternative:
if age<20:
    print('hi')
else:
    print('hello')