Skip to content

Comparaison chaînée (a < x < b) en Python

En Python, les comparaisons peuvent être chaînées. Vous pouvez écrire a < x et x < b comme a < x < b comme en mathématiques.

Cet article décrit le contenu suivant.

  • Chaîne de comparaisons multiples
  • Exemple 1 : plage numérique
  • Exemple 2 : Vérifier si plusieurs valeurs sont toutes égales
  • Attention à ne pas abuser

Chaîne de comparaisons multiples

Par exemple, a < x < b est équivalent à a < x et x < b.

Les comparaisons peuvent être enchaînées arbitrairement, par exemple, x < y <= z est équivalent à x < y et y <= z, sauf que y n’est évalué qu’une seule fois (mais dans les deux cas z n’est pas du tout évalué lorsque x < y est trouvé être faux).

Formellement, si a, b, c, …, y, z sont des expressions et op1, op2, …, opN sont des opérateurs de comparaison, alors a op1 b op2 c … y opN z est équivalent à a op1 b et b op2 c et … y opN z, sauf que chaque expression est évaluée au plus une fois.
6. Expressions – Comparaisons — Documentation Python 3.9.1

Si a,b, c, …, y, z sont des expressions et op1, op2, …, opN sont des opérateurs de comparaison (tels que < ou >), les deux suivants sont équivalents.

a op1 b op2 c ... y opN z
a op1 b and b op2 c and ... y opN z

Exemples spécifiques :

x = 15
print(10 < x < 20)
# True

print(10 < x and x < 20)
# True

x = 0
print(10 < x < 20)
# False

print(10 < x and x < 20)
# False

Exemples plus complexes :

x = 15
y = 25

print(10 < x < 20 < y < 30)
# True

print(10 < x and x < 20 and 20 < y and y < 30)
# True

x = 15
y = 40

print(10 < x < 20 < y < 30)
# False

print(10 < x and x < 20 and 20 < y and y < 30)
# False

Comme indiqué dans la documentation officielle, chaque expression est évaluée au plus une fois lorsqu’elle est enchaînée.

Par exemple, définissez une fonction simple qui renvoie ses arguments tels quels. print() est exécuté pour confirmer que la fonction a été appelée.

def test(x):
    print('function is called')
    return(x)

print(test(15))
# function is called
# 15

Si les comparaisons sont chaînées, la fonction n’est appelée qu’une seule fois.

print(10 < test(15) < 20)
# function is called
# True

Dans le cas de et, la fonction est appelée deux fois.

print(10 < test(15) and test(15) < 20)
# function is called
# function is called
# True

Dans X et Y, si X vaut False, Y n’est pas évalué. Par conséquent, dans le cas suivant, la fonction n’est appelée qu’une seule fois, qu’elle soit chaînée ou non.

print(10 < test(0) < 20)
# function is called
# False

print(10 < test(0) and test(0) < 20)
# function is called
# False

C’est ce qu’on appelle l’évaluation de court-circuit. Voir l’article suivant pour plus de détails.

Dans tous les cas, lors du chaînage, chaque expression n’est évaluée qu’une seule fois au plus, donc le chaînage est plus efficace lors de la comparaison des résultats de fonctions complexes.

Exemple 1 : plage numérique

Lorsqu’une plage de nombres est utilisée comme condition, les comparaisons enchaînées sont utiles.

x = 15

if 10 < x < 20:
    print('result: 10 < x < 20')
else:
    print('result: x <= 10 or 20 <= x')
# result: 10 < x < 20

x = 30

if 10 < x < 20:
    print('result: 10 < x < 20')
else:
    print('result: x <= 10 or 20 <= x')
# result: x <= 10 or 20 <= x

Exemple 2 : Vérifier si plusieurs valeurs sont toutes égales

Une autre utilisation pratique consiste à vérifier si plusieurs variables et expressions sont toutes égales.

Le chaînage avec l’opérateur de comparaison == renvoie True uniquement si toutes les valeurs sont égales.

a = 10
b = 10
c = 10

if a == b == c:
    print('all equal')
else:
    print('not all equal')
# all equal

S’il existe ne serait-ce qu’une seule valeur différente, False est renvoyé.

a = 10
b = 1
c = 10

if a == b == c:
    print('all equal')
else:
    print('not all equal')
# not all equal

Soyez prudent lorsque vous utilisez l’opérateur de comparaison != qui renvoie True lorsque les valeurs ne sont pas équivalentes. Toutes les combinaisons de valeurs ne sont pas évaluées, donc même s’il existe des valeurs équivalentes, True est renvoyé en fonction de l’ordre.

a = 10
b = 1
c = 100

print(a != b != c)
# True

a = 10
b = 10
c = 1

print(a != b != c)
# False

a = 10
b = 1
c = 10

print(a != b != c)
# True

Une façon de vérifier que plusieurs valeurs sont toutes uniques consiste à les stocker dans une liste, puis à vérifier les doublons. Voir l’article suivant.

Notez que == et != comparent les valeurs. L’utilisation est, n’est pas de comparer l’identité des objets.

Par exemple, lors de la comparaison d’un entier int avec un nombre à virgule flottante float, == renvoie True si les valeurs sont équivalentes, mais renvoie False car ce sont des objets différents.

i = 10
print(type(i))
# <class 'int'>

f = 10.0
print(type(f))
# <class 'float'>

print(i == f)
# True

print(i is f)
# False

Attention à ne pas abuser

La comparaison chaînée peut être écrite de différentes manières, mais attention, le code peut être difficile à lire dans certains cas.

Par exemple, l’opérateur in, qui teste si une liste contient un élément particulier, peut également être chaîné, mais c’est probablement déroutant pour la plupart des gens. À moins que vous n’ayez un fort avantage dans le sens où « chaque expression n’est évaluée qu’une seule fois », vous devez utiliser and.

a = 100
l = [0, 10, 100, 1000]

print(50 < a in l)
# True

print(50 < a and a in l)
# True