Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Licence CC BY-NC-ND Thierry Parmentelat & Arnaud Legout Inria - UCA

Complément - niveau basique

Dans ce complément nous résumons ce qu’il faut savoir pour écrire une condition dans un if.

Expression vs instruction

Nous avons déjà introduit la différence entre instruction et expression, lorsque nous avons vu l’expression conditionnelle :

Ainsi parmi les notions que nous avons vues jusqu’ici, nous pouvons citer dans un ordre arbitraire :

Instructions Expressions
affectation appel de fonction
import opérateurs is, in, ==, ...
instruction if expression conditionnelle
instruction for compréhension(s)

Toutes les expressions sont éligibles

Comme condition d’une instruction if, on peut mettre n’importe quelle expression. On l’a déjà signalé, il n’est pas nécessaire que cette expression retourne un booléen :

# dans ce code le test 
# if n % 3:
# est équivalent à
# if n % 3 != 0:

for n in (18, 19):
    if n % 3:
        print(f"{n} non divisible par trois")
    else:
        print(f"{n} divisible par trois")
18 divisible par trois
19 non divisible par trois

Une valeur est-elle “vraie” ?

Se pose dès lors la question de savoir précisément quelles valeurs sont considérées comme vraies par l’instruction if.

Parmi les types de base, nous avons déjà eu l’occasion de l’évoquer, les valeurs fausses sont typiquement :

Pour en avoir le cœur net, pensez à utiliser dans le terminal interactif la fonction bool. Comme pour toutes les fonctions qui portent le nom d’un type, la fonction bool est un constructeur qui fabrique un objet booléen.

Si vous appelez bool sur un objet, la valeur de retour - qui est donc par construction une valeur booléenne - vous indique, cette fois sans ambiguïté - comment se comportera if avec cette entrée.

def show_bool(x):
    print(f"condition {repr(x):>10} considérée comme {bool(x)}")
for exp in [None, "", 'a', [], [1], (), (1, 2), {}, {'a': 1}, set(), {1}]:
    show_bool(exp)
condition       None considérée comme False
condition         '' considérée comme False
condition        'a' considérée comme True
condition         [] considérée comme False
condition        [1] considérée comme True
condition         () considérée comme False
condition     (1, 2) considérée comme True
condition         {} considérée comme False
condition   {'a': 1} considérée comme True
condition      set() considérée comme False
condition        {1} considérée comme True

Quelques exemples d’expressions

Référence à une variable et dérivés

a = list(range(4))
print(a)
[0, 1, 2, 3]
if a:
    print("a n'est pas vide")
if a[0]:
    print("on ne passe pas par ici")
if a[1]:
    print("a[1] n'est pas nul")
a n'est pas vide
a[1] n'est pas nul

Appels de fonction ou de méthode

chaine = "jean"
if chaine.upper():
    print("la chaine mise en majuscule n'est pas vide")
la chaine mise en majuscule n'est pas vide
# on rappelle qu'une fonction qui ne fait pas 'return' retourne None
def procedure(a, b, c):
    "cette fonction ne retourne rien"
    pass

if procedure(1, 2, 3):
    print("ne passe pas ici car procedure retourne None")
else:
    print("par contre on passe ici")
par contre on passe ici

Compréhensions

Il découle de ce qui précède qu’on peut tout à fait mettre une compréhension comme condition, ce qui peut être utile pour savoir si au moins un élément remplit une condition, comme par exemple :

inputs = [23, 65, 24]

# y a-t-il dans inputs au moins un nombre 
# dont le carré est de la forme 10*n+5
def condition(n):
    return (n * n) % 10 == 5

if [value for value in inputs if condition(value)]:
    print("au moins une entrée convient")
au moins une entrée convient

Opérateurs

Nous avons déjà eu l’occasion de rencontrer la plupart des opérateurs de comparaison du langage, dont voici à nouveau les principaux :

Famille Exemples
Égalité ==, !=, is, is not
Appartenance in
Comparaison <=, <, >, >=
Logiques and, or, not

Complément - niveau intermédiaire

Remarques sur les opérateurs

Voici enfin quelques remarques sur ces opérateurs

opérateur d’égalité ==

L’opérateur == ne fonctionne en général (sauf pour les nombres) que sur des objets de même type ; c’est-à-dire que notamment un tuple ne sera jamais égal à une liste :

[] == ()
False
[1, 2] == (1, 2)
False

opérateur logiques

Comme c’est le cas avec par exemple les opérateurs arithmétiques, les opérateurs logiques ont une priorité, qui précise le sens des phrases non parenthésées. C’est-à-dire pour être explicite, que de la même manière que

12 + 4 * 8

est équivalent à

12 + ( 4 * 8 )

pour les booléens il existe une règle de ce genre et

a and not b or c and d

est équivalent à

(a and (not b)) or (c and d)

Mais en fait, il est assez facile de s’emmêler dans ces priorités, et c’est pourquoi il est très fortement conseillé de parenthéser.

opérateurs logiques (2)

Remarquez aussi que les opérateurs logiques peuvent être appliqués à des valeurs qui ne sont pas booléennes :

2 and [1, 2]
[1, 2]
None or "abcde"
'abcde'

Dans la logique de l’évaluation paresseuse qu’on a vue récemment, remarquez que lorsque l’évaluation d’un and ou d’un or ne peut pas être court-circuitée, le résultat est alors toujours le résultat de la dernière expression évaluée :

1 and 2 and 3
3
1 and 2 and 3 and '' and 4
''
[] or "" or {}
{}
[] or "" or {} or 4 or set()
4

Expression conditionnelle dans une instruction if

En toute rigueur on peut aussi mettre un <> if <> else <> - donc une expression conditionnelle - comme condition dans une instruction if. Nous le signalons pour bien illustrer la logique du langage, mais cette pratique n’est bien sûr pas du tout conseillée.

# cet exemple est volontairement tiré par les cheveux 
# pour bien montrer qu'on peut mettre 
# n'importe quelle expression comme condition
a = 1

# ceci est franchement illisible
if 0 if not a else 2:
    print("une construction illisible")

# et encore pire
if 0 if a else 3 if a + 1 else 2:
    print("encore pire")
une construction illisible

Pour en savoir plus

https://docs.python.org/3/tutorial/datastructures.html#more-on-conditions

Types définis par l’utilisateur

Pour anticiper un tout petit peu, nous verrons que les classes en Python vous donnent le moyen de définir vos propres types d’objets. Nous verrons à cette occasion qu’il est possible d’indiquer à python quels sont les objets de type MaClasse qui doivent être considérés comme True ou comme False.

De manière plus générale, tous les traits natifs du langage sont redéfinissables sur les classes. Nous verrons par exemple également comment donner du sens à des phrases comme

mon_objet = MaClasse()
if mon_objet:
    <faire quelque chose>

ou encore

mon_objet = MaClasse()
for partie in mon_objet:
    <faire quelque chose sur partie>

Mais n’anticipons pas trop, rendez-vous en semaine 6.