Python prend en charge les opérateurs de comparaison de base suivants :
| Opérateur | Opération | Description |
|---|---|---|
> |
« supérieur à » |
a > b est True si a est strictement supérieur en valeur à b
|
< |
« inférieur à » |
a < b est True si a est strictement inférieur en valeur à b
|
== |
« égal à » |
a == b est True si a est strictement égal à b en valeur |
>= |
« supérieur ou égal à » |
a >= b est True si a > b OU a == b en valeur |
<= |
« inférieur ou égal à » |
a <= b est True si a < b ou a == b en valeur |
!= |
« différent de » |
a != b est True si a == b est False
|
is |
« identité » |
a is b est True si et seulement si a et b sont le même objet
|
is not |
« identité niée » |
a is not b est True si a et b ne sont pas le même objet
|
in |
« test d'appartenance » |
a in b est True si a est un membre, un sous-ensemble ou un élément de b
|
not in |
« test de non-appartenance » |
a not in b est True si a n'est pas un membre, un sous-ensemble ou un élément de b
|
Ils ont tous la même priorité (plus élevée que celle des opérations booléennes, mais plus faible que celle des opérations arithmétiques ou binaires).
Des objets de types différents (sauf les types numériques) ne sont jamais considérés comme égaux par défaut.
Des instances non identiques d'une class ne seront pas non plus considérées comme égales, à moins que la class ne définisse des méthodes spéciales de comparaison enrichie qui personnalisent le comportement de comparaison par défaut de object.
La personnalisation via rich comparisons sera abordée dans un exercice ultérieur.
Pour (beaucoup) plus de détails sur ce sujet, consulte les comparaisons de valeurs dans la documentation Python.
Les types numériques constituent (en grande partie) une exception à cette règle d'appariement des types.
Un integer peut être considéré comme égal à un float (ou un octal égal à un hexadecimal), tant que les types peuvent être convertis implicitement pour la comparaison.
Pour les autres types numériques de la bibliothèque standard de Python (complex, decimal, fractions), les opérateurs de comparaison sont définis là où ils « ont un sens » (là où la conversion implicite ne change pas le résultat), mais lèvent une TypeError si les objets sous-jacents ne peuvent pas être convertis précisément pour la comparaison.
Pour plus d'informations sur les règles que Python utilise pour la conversion numérique, consulte les conversions arithmétiques dans la documentation Python.
>>> import fractions
# A string cannot be converted to an int.
>>> 17 == '17'
False
# An int can be converted to float for comparison.
>>> 17 == 17.0
True
# The fraction 6/3 can be converted to the int 2
# The int 2 can be converted to 0b10 in binary.
>>> 6/3 == 0b10
True
# An int can be converted to a complex number with a 0 imaginary part.
>>> 17 == complex(17)
True
# The fraction 2/5 can be converted to the float 0.4
>>> 0.4 == 2/5
True
>>> complex(2/5, 1/2) == complex(0.4, 0.5)
True
Toute comparaison ordonnée entre un nombre et un type NaN (not a number, c'est-à-dire « pas un nombre ») est False.
Un effet de bord déroutant de la définition de NaN en Python est que NaN n'est jamais égal à NaN.
>>> x = float('NaN')
>>> 3 < x
False
>>> x < 3
False
# NaN never compares equal to NaN
>>> x == x
False
Contrairement aux nombres, les strings (str) sont comparés selon l'ordre lexicographique, en utilisant leurs points de code Unicode individuels (le résultat du passage de chaque point de code du str à la fonction native ord(), qui renvoie un int).
Si tous les points de code des deux strings correspondent et sont dans le même ordre, les deux strings sont considérés comme égaux.
Cette comparaison se fait par paires : le premier avec le premier, le deuxième avec le deuxième, etc.
En Python 3.x, str et bytes ne peuvent pas être convertis ni comparés directement.
>>> 'Python' > 'Rust'
False
>>> 'Python' > 'JavaScript'
True
# Examples with Mandarin.
# hello < goodbye
>>> '你好' < '再见'
True
# ord() of first characters
>>> ord('你'), ord('再')
(20320, 20877)
# ord() of second characters
>>> ord('好'), ord('见')
(22909, 35265)
# And with Korean words.
# Pretty < beautiful.
>>> '예쁜' < '아름다운'
False
>>> ord('예'), ord('아')
(50696, 50500)
Les opérateurs de comparaison peuvent être chaînés arbitrairement, c'est-à-dire qu'ils peuvent être utilisés dans n'importe quelle combinaison, de n'importe quelle longueur.
Note que l'évaluation d'une expression se fait de left à right.
Par exemple, x < y <= z équivaut à x < y and y <= z, sauf que y n'est évalué qu'une seule fois.
Dans les deux cas, z n'est pas du tout évalué lorsque x < y s'avère être False.
C'est ce qu'on appelle souvent short-circuit evaluation : l'évaluation s'arrête dès que la valeur de vérité de l'expression a déjà été déterminée.
Le Short circuiting est pris en charge par divers opérateurs booléens et fonctions, ainsi que par le chaînage de comparaisons en Python.
Contrairement à de nombreux autres langages de programmation, notamment C, C++, C# et Java, les expressions chaînées comme a < b < c en Python ont une interprétation mathématique et une priorité conventionnelles.
>>> x = 2
>>> y = 5
>>> z = 10
>>> x < y < z
True
>>> x < y > z
False
>>> x > y < z
False
Les opérateurs is et is not testent l'identité d'un objet, par opposition à sa valeur.
L'identité d'un objet ne change jamais après sa création et peut être obtenue à l'aide de la fonction id().
<apple> is <orange> est évalué à True si et seulement si id(<apple>) == id(<orange>).
<apple> is not <orange> donne le résultat inverse.
En raison de leur statut de singleton, None et NotImplemented doivent toujours être comparés à des éléments en utilisant is et is not.
Consulte la documentation de référence de Python sur les comparaisons de valeurs et le PEP8 pour plus de détails sur cette convention.
>>> my_fav_numbers = [1, 2, 3]
>>> your_fav_numbers = my_fav_numbers
>>> my_fav_numbers is your_fav_numbers
True
# The returned id will differ by system and python version.
>>> id(my_fav_numbers)
4517478208
# your_fav_numbers is only an alias pointing to the original my_fav_numbers object.
# Assigning a new name does not create a new object.
>>> id(your_fav_numbers)
4517478208
>>> my_fav_numbers is not your_fav_numbers
False
>>> my_fav_numbers is not None
True
>>> my_fav_numbers is NotImplemented
False
Les opérateurs in et not in testent l'appartenance.
<fish> in <soup> est évalué à True si <fish> est un membre de <soup> (si <fish> est un sous-ensemble de <soup> ou est contenu dans <soup>), et à False sinon.
<fish> not in <soup> renvoie la négation, c'est-à-dire l'opposé de <fish> in <soup>.
Pour les types string et bytes, <name> in <fullname> vaut True si et seulement si <name> est une sous-chaîne de <fullname>.
# A set of lucky numbers.
>>> lucky_numbers = {11, 22, 33}
>>> 22 in lucky_numbers
True
>>> 44 in lucky_numbers
False
# A dictionary of employee information.
>>> employee = {'name': 'John Doe',
'id': 67826, 'age': 33,
'title': 'ceo'}
# Checking for the membership of certain keys.
>>> 'age' in employee
True
>>> 33 in employee
False
>>> 'lastname' not in employee
True
# Checking for substring membership
>>> name = 'Super Batman'
>>> 'Bat' in name
True
>>> 'Batwoman' in name
False
Dans cet exercice, on va implémenter certaines règles du Blackjack, comme la manière dont le jeu se joue et dont on compte les points.
Note : dans cet exercice, A désigne l'as, J le valet, Q la dame et K le roi.
Les jokers sont écartés.
On suppose un jeu standard de 52 cartes aux enseignes françaises, mais dans la plupart des versions, plusieurs jeux sont mélangés ensemble pour jouer.
Au Blackjack, c'est à chaque joueur de décider si un as vaut 1 ou 11 points (on y reviendra plus tard).
Les figures (J, Q, K) valent 10 points, et toute autre carte vaut sa valeur « pip » (numérique).
Définis la fonction value_of_card(<card>) avec le paramètre card.
La fonction doit renvoyer la valeur numérique de la string passée en argument.
Comme un as peut prendre plusieurs valeurs (1 ou 11), cette fonction doit fixer pour l'instant la valeur d'un as à 1.
Plus tard, tu implémenteras une fonction qui détermine la valeur d'un as à partir d'une main existante.
>>> value_of_card('K')
10
>>> value_of_card('4')
4
>>> value_of_card('A')
1
Définis la fonction higher_card(<card_one>, <card_two>) avec les paramètres card_one et card_two.
Pour le calcul des points, la valeur de J, Q ou K est 10.
La fonction doit renvoyer la carte qui a la valeur la plus élevée pour le calcul des points.
Si les deux cartes ont la même valeur, renvoie les deux.
On peut renvoyer les deux cartes en utilisant une virgule dans l'instruction return :
# Using a comma in a return creates a Tuple. Tuples will be covered in a later exercise.
>>> def returning_two_values(value_one, value_two):
return value_one, value_two
>>> returning_two_values('K', '3')
('K', '3')
Un as peut prendre plusieurs valeurs, donc pour cette tâche, on fixera la valeur des cartes A à 1.
>>> higher_card('K', '10')
('K', '10')
>>> higher_card('4', '6')
'6'
>>> higher_card('K', 'A')
'K'
Comme on l'a mentionné plus haut, un as peut valoir soit 1 soit 11 points. Les joueurs essaient de s'approcher le plus possible de 21 points, sans aller au-delà de 21 (ce qu'on appelle « sauter »).
Définis la fonction value_of_ace(<card_one>, <card_two>) avec les paramètres card_one et card_two, qui sont deux cartes déjà présentes dans la main avant de recevoir un as.
Ta fonction devra décider si l'as à venir vaudra 1 ou 11, et renvoyer cette valeur.
Rappelle-toi : la valeur de la main avec l'as doit être aussi élevée que possible sans dépasser 21.
Indice : si on a déjà un as en main, la valeur de l'as à venir sera de 1.
>>> value_of_ace('6', 'K')
1
>>> value_of_ace('7', '3')
11
Si un joueur reçoit un as (A) et une carte de dix (10, K, Q ou J) comme deux premières cartes, il obtient un score de 21.
On parle alors d'une main blackjack.
Définis la fonction is_blackjack(<card_one>, <card_two>) avec les paramètres card_one et card_two, qui sont deux cartes.
Détermine si cette main de deux cartes est un blackjack, et renvoie le booléen True si c'est le cas, False sinon.
Note : le calcul du score peut se faire de plusieurs façons. Mais si possible, on aimerait que tu vérifies s'il y a un as et une carte de dix dans la main (ou à une certaine position), plutôt que de sommer les valeurs de la main.
>>> is_blackjack('A', 'K')
True
>>> is_blackjack('10', '9')
False
Si les deux premières cartes d'une main ont la même valeur (par exemple, deux six, ou un Q et un K), un joueur peut choisir de les traiter comme deux mains distinctes.
C'est ce qu'on appelle « séparer les paires ».
Définis la fonction can_split_pairs(<card_one>, <card_two>) avec les paramètres card_one et card_two, qui sont deux cartes.
Détermine si cette main de deux cartes peut être séparée en deux paires.
Si la main peut être séparée, renvoie le booléen True, sinon renvoie False.
>>> can_split_pairs('Q', 'K')
True
>>> can_split_pairs('10', 'A')
False
Quand les deux cartes distribuées au départ totalisent 9, 10 ou 11 points, un joueur peut placer une mise supplémentaire égale à sa mise d'origine. C'est ce qu'on appelle « doubler la mise ».
Définis la fonction can_double_down(<card_one>, <card_two>) avec les paramètres card_one et card_two, qui sont deux cartes.
Détermine si on peut doubler la mise sur cette main de deux cartes, et renvoie le booléen True dans ce cas, False sinon.
>>> can_double_down('A', '9')
True
>>> can_double_down('10', '2')
False
Inscris-toi sur Exercism pour apprendre et maîtriser Python avec 17 concepts146 exercices, et un vrai mentorat humain, le tout gratuitement.