cours
30 astuces Python pour mieux coder avec des exemples
Les compétences en codage Python sont de plus en plus demandées depuis quelques années. Pour vous aider à développer vos compétences en programmation Python, nous avons sélectionné 30 astuces Python intéressantes que vous pouvez utiliser pour améliorer votre code. Essayez d'en apprendre un par jour pendant les 30 prochains jours, et consultez notre article sur les meilleures pratiques de Python pour vous assurer que votre code est le meilleur de sa catégorie.
Si vos compétences en Python ne sont pas à la hauteur, vous pouvez également les affiner grâce à notre cursus de compétences en Python.
#1 Tranchage
a = "Hello World!"
print(a[::-1])
"""
!dlroW olleH
"""
Le slicing est une fonctionnalité de Python qui s'appuie sur l'indexation pour permettre aux utilisateurs d'accéder à un sous-ensemble d'une séquence. Un index est simplement la position d'un élément dans une séquence. Si le type de séquence est mutable, vous pouvez utiliser le découpage en tranches pour extraire et modifier les données.
Note: Nous pouvons également utiliser le découpage en tranches sur une séquence immuable, mais essayer de modifier la tranche soulèvera une TypeError.
Le format dans lequel les tranches sont mises en œuvre est le suivant : séquence[start:stop:step]. Si aucune valeur n'est spécifiée dans les paramètres start, stop et step, la séquence appliquera les valeurs par défaut. Les valeurs par défaut sont les suivantes :
- La valeur par défaut de "start" est 0
- "stop" correspond par défaut à la longueur de la séquence
- La valeur par défaut de "step" est 1 si elle n'est pas spécifiée.
Lorsque la séquence [start:stop] est utilisée, les éléments renvoyés vont de l'indice de départ à l'indice de fin- 1 (l'indice de fin n'est pas inclus).
Nous pouvons également transmettre des indices négatifs, qui peuvent être utilisés pour inverser la séquence. Par exemple, dans une liste de 4 éléments, l'indice 0 est aussi l'indice -4, et le dernier indice est aussi -1. Dans l'exemple de code ci-dessus, cette connaissance a été appliquée au paramètre d'étape de la séquence. Par conséquent, la chaîne a été imprimée à l'envers, en commençant par la fin de la séquence à l'index 0.
#2 Inplace Swap / Simultaneous Assignment (échange en lieu et place / cession simultanée)
a = 10
b = 5
print(f"First: {a, b}")
"""
First: (10, 5)
"""
a, b = b, a + 2
print(f"Second: {a, b}")
"""
Second: (5, 12)
"""
Si votre première impression était que la valeur de b serait de 7 au lieu de 12, vous êtes tombé dans le piège de l'échange de places.
En Python, nous pouvons déballer les itérables vers des variables en une seule affectation en utilisant le déballage automatique. Par exemple :
a, b, c = [1, 2, 3]
print(a)
print(b)
print(c)
"""
1
2
3
"""
Nous pouvons également rassembler plusieurs valeurs dans une seule variable en utilisant * - cette astuce de Python s'appelle le packing. Vous trouverez ci-dessous un exemple d'emballage.
a, b* = 1, 2, 3
print(a, b)
"""
1 [2, 3]
"""
La combinaison de l'emballage et du déballage automatiques donne lieu à une technique connue sous le nom d'affectation simultanée. Nous pouvons utiliser l'affectation simultanée pour affecter une série de valeurs à une série de variables.
#Liste n°3 vs. Tuples
import sys
a = [1, 2, 3, 4, 5]
b = (1, 2, 3, 4, 5)
print(f"List size: {sys.getsizeof(a)} bytes")
print(f"Tuple size: {sys.getsizeof(b)} bytes")
"""
List size: 112 bytes
Tuple size: 96 bytes
"""
La plupart des programmeurs Python sont familiarisés avec la structure de données de type liste. Il n'en va pas de même pour les tuples. Ils sont tous deux itérables, permettent l'indexation et le stockage de types de données hétérogènes. Mais il existe des situations dans lesquelles l'utilisation d'un tuple peut être préférée à celle d'une liste.
Tout d'abord, les listes sont mutables, ce qui signifie que nous pouvons les modifier à notre guise :
a = [1,2,3,4,5]
a[2] = 8
print(a)
"""
[1,2,8,4,5]
"""
Les tuples, en revanche, sont immuables, ce qui signifie qu'une tentative de modification entraînera une TypeError.
Pour cette raison, les tuples sont plus efficaces en termes de mémoire puisque Python peut allouer le bloc de mémoire adéquat requis pour les données. En revanche, dans une liste, de la mémoire supplémentaire doit être allouée juste au cas où nous l'étendrions - c'est ce qu'on appelle l'allocation dynamique de mémoire.
Dans les cas où vous ne souhaitez pas que les données soient modifiées, il est préférable d'utiliser une structure de données de type tuple plutôt qu'une liste pour des raisons de mémoire. Les tuples sont également plus rapides que les listes.
Apprenez-en plus sur les structures de données Python dans ce tutoriel.
Générateurs #4
a = [x * 2 for x in range(10)]
b = (x * 2 for x in range(10))
print(a)
print(b)
"""
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
<generator object <genexpr> at 0x7f61f8808b50>
"""
Les compréhensions de listes sont la manière Python de créer une liste à partir d'un autre itérable - C'est beaucoup plus rapide que d'utiliser une boucle for. Mais que se passe-t-il si vous changez accidentellement les crochets de [] en ()? Vous obtenez un objet générateur.
En Python, les parenthèses arrondies avec la logique de compréhension de liste créent ce que l'on appelle un objet générateur. Les générateurs sont un type particulier d'itérable. Contrairement aux listes, ils ne stockent pas leurs articles. Au lieu de cela, ils stockent des instructions pour générer chaque élément dans l'ordre et l'état actuel des itérations.
Chaque élément n'est généré que sur demande à l'aide d'une technique appelée évaluation paresseuse. Le principal avantage de cette astuce Python utilisant un générateur est qu'elle utilise moins de mémoire puisque toute la séquence n'est pas construite en une seule fois.
#5 Aliasing
a = [1, 2, 3, 4 ,5]
b = a
# Change the 4th index in b
b[4] = 7
print(id(a))
print(id(b))
print(a) # Remember we did not explicitly make changes to a.
"""
2278459070720
2278459070720
[1, 2, 3, 4, 7]
"""
Python est un langage de programmation orienté objet - tout est objet. Ainsi, l'affectation d'un objet à un identificateur revient à créer une référence à l'objet.
Lorsque nous attribuons un identifiant à un autre identifiant, nous nous retrouvons avec deux identifiants qui font référence au même objet. Il s'agit d'un concept connu sous le nom d'aliasing. Les modifications apportées à l'un des alias auront une incidence sur l'autre. Parfois, ce comportement est souhaité, mais souvent, il nous prend au dépourvu.
Une façon de contourner ce problème est de s'abstenir d'utiliser l'alias lors de l'utilisation d'objets mutables. Une autre solution pourrait consister à créer un clone de l'objet original plutôt qu'une référence.
La façon la plus simple de créer un clone est d'utiliser le découpage en tranches :
b = a[:]
Cela créera une nouvelle référence à un objet liste dans l'identifiant b.
Vous pourriez imaginer bien d'autres solutions, comme appeler list(a) lors de l'affectation des données à un autre identifiant et utiliser la méthode copy().
#6 L'opérateur "not" (pas)
a = []
print(not a)
"""
True
"""
Notre prochaine astuce Python est la façon la plus simple de vérifier si votre structure de données est vide en utilisant l'opérateur not. La fonction intégrée de Python not est un opérateur logique qui renvoie True si l'expression n'est pas vraie, sinon il renvoie False - il inverse la valeur de vérité des expressions booléennes et des objets.
Une autre façon de l'utiliser est dans une instruction if :
if not a:
# do something...
Lorsque a est vrai alors l'élément pas renverra Fauxet vice versa.
Il est difficile de s'y retrouver, mais il faut essayer.
#7 F-strings
first_name = "John"
age = 19
print(f"Hi, I'm {first_name} and I'm {age} years old!")
"""
Hi, I'm John and I'm 19 years old!
"""
Python 3.6 a introduit une fonctionnalité intéressante appelée f-strings pour simplifier ce processus. Il est utile de comprendre comment les chaînes étaient formatées avant la nouvelle version pour mieux apprécier la nouvelle méthode.
Voici comment les chaînes de caractères étaient formatées auparavant :
first_name = "John"
age = 19
print("Hi, I'm {} and I'm {} years old!".format(first_name, age))
"""
Hi, I'm John and I'm 19 years old!
"""
Pour l'essentiel, la nouvelle méthode de formatage est plus rapide, plus lisible, plus concise et plus difficile à mettre en œuvre.
Une autre utilisation de f-strings consiste à imprimer le nom d'un identifiant avec sa valeur. Ceci a été introduit dans Python 3.8.
x = 10
y = 20
print(f"{x = }, {y = }")
"""
x = 10, y = 20
"""
Consultez ce tutoriel sur le formatage des chaînes de caractères F en Python pour en savoir plus.
#8 Le paramètre 'end' des fonctions d'impression
a = ["english", "french", "spanish", "german", "twi"]
for language in a:
print(language, end=" ")
"""
english french spanish german twi
"""
Il est assez courant d'utiliser un print sans définir aucun de ses paramètres optionnels. Par conséquent, plusieurs Pythonistes ignorent que vous pouvez contrôler la sortie dans une certaine mesure.
Un paramètre facultatif que nous pouvons modifier est la fin. Le paramètre de fin spécifie ce qui doit être affiché à la fin d'un appel à une commande print à la fin d'un appel à l'instruction print.
La valeur par défaut de end est "\n" qui indique à Python de commencer une nouvelle ligne. Dans le code ci-dessus, nous l'avons remplacé par un espace. Ainsi, la sortie renvoie tous les éléments de notre liste sont imprimés sur la même ligne.
#9 Append to Tuple
a = (1, 2, [1, 2, 3])
a[2].append(4)
print(a)
"""
(1, 2, [1, 2, 3, 4])
"""
Nous savons déjà que les tuples sont immuables - voir l'astuce Python #3 List vs. Tuples. Toute tentative de modification de l'état d'un tuple entraînerait une erreur de type (TypeError). Mais si vous considérez un objet tuple comme une séquence de noms dont les liens avec des objets ne peuvent être modifiés, vous verrez les choses différemment.
Les deux premiers éléments de notre tuple sont des entiers - ils sont immuables. Le dernier élément de notre tuple est une liste, un objet mutable en Python.
Si nous considérons que notre liste n'est qu'un nom parmi d'autres dans une séquence liée à un objet qui ne peut être modifié, nous nous rendons compte que la liste peut toujours être modifiée à l'intérieur du tuple.
Est-ce que nous vous recommandons de le faire en pratique ? Probablement pas, mais cela fait partie des choses qu'il est bon de savoir !
#10 Fusionner des dictionnaires
a = {"a": 1, "b": 2}
b = {"c": 3, "d": 4}
a_and_b = a | b
print(a_and_b)
"""
{"a": 1, "b": 2, "c": 3, "d": 4}
"""
Dans Python 3.9 et plus, il est possible de fusionner des dictionnaires en utilisant | (bitewise OR). Il n'y a pas grand-chose d'autre à dire sur cette astuce particulière de Python, si ce n'est qu'il s'agit d'une solution beaucoup plus lisible !
#11 Opérateur ternaire / Expressions conditionnelles
condition = True
name = "John" if condition else "Doe"
print(name)
"""
John
"""
Dans le code ci-dessus, vous pouvez voir ce que l'on appelle un opérateur ternaire - il est également appelé expression conditionnelle parmi d'autres noms. Nous utilisons des opérateurs ternaires pour évaluer les choses selon qu'une condition est vraie ou Faux.
Nous aurions également pu écrire notre code comme suit :
condition = True
if condition:
name = "John"
else:
name = "Doe"
print(name)
"""
John
"""
Bien que les deux ensembles de code produisent le même résultat, remarquez que le conditionnel ternaire nous permet d'écrire un code beaucoup plus court et plus clair. C'est ce que les pythonistes appelleraient la manière la plus "Python" d'écrire du code.
#12 Supprimer les doublons des listes
a = [1, 1, 2, 3, 4, 5, 5, 5, 6, 7, 2, 2]
print(list(set(a)))
"""
[1, 2, 3, 4, 5, 6, 7]
"""
La manière la plus simple de supprimer les éléments dupliqués d'une liste est de convertir la liste en un ensemble (puis de revenir à une liste si vous le souhaitez).
Basés sur la mutabilité, les ensembles et les listes sont assez similaires en Python. Nous pouvons ajouter et retirer des éléments de ces deux structures de données à volonté, mais elles restent extrêmement différentes.
Les listes sont ordonnées, indexées par zéro et mutables. Les ensembles sont non ordonnés et non indexés. Les éléments d'un ensemble doivent être d'un type immuable, même si l'ensemble lui-même est mutable - toute tentative de récupération d'un élément via un index ou de modification d'un élément entraînera une erreur.
Une autre différence essentielle entre les ensembles et les listes est que les ensembles ne peuvent pas contenir de doublons. C'est ce qui nous a permis de supprimer les éléments en double de notre liste.
#13 Standalone Underscore
>>> print(_)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
>>> 1 + 2
3
>>> print(_)
3
Le tiret bas (_) est un identifiant légal en Python, il est donc possible de l'utiliser pour référencer un objet. Mais l'underscore a également une autre responsabilité : stocker le résultat de la dernière évaluation.
La documentation indique que "l'interprète interactif met à disposition le résultat de la dernière évaluation dans la variable _. (Il est stocké dans le module builtins, avec les fonctions intégrées telles que print)".
Comme nous n'avons pas assigné un objet à underscore avant de l'appeler à la première ligne, nous avons obtenu une erreur. Cependant, lorsque nous avons calculé le résultat de 1 + 2, l'interprète interactif a stocké le résultat dans l'identifiant _ pour nous.
#14 Underscore pour ignorer les valeurs
for _ in range(100):
print("The index doesn't matter")
"""
The index doesn't matter
The index doesn't matter
...
"""
Dans l'astuce Python n°13, nous avons découvert que l'interpréteur interactif met à disposition le dernier résultat d'une évaluation dans l'identifiant underscore (_), mais ce n'est pas son seul cas d'utilisation.
Nous pouvons également l'utiliser pour représenter des objets dont nous ne nous soucions pas ou que nous n'utiliserons pas à un stade ultérieur du programme. Ceci est important car l'utilisation d'un identifiant au lieu d'un trait de soulignement (_) entraînera une erreur F841 lorsque nous tenterons d'effectuer une analyse de notre programme. Une erreur F841 indique simplement qu'un nom de variable locale a été attribué mais n'a pas été utilisé dans le programme, ce qui est une mauvaise pratique.
#15 Underscores de fin
list_ = [0, 1, 2, 3, 4]
global_ = "Hi there"
Dans la continuité des deux dernières astuces, l'utilisation du trait de soulignement (_) de Python, un autre objectif de ce dernier est d'éviter les conflits avec les mots-clés de Python.
La PEP 8 mentionne qu'un trait de soulignement de fin (_) doit être "utilisé par convention pour éviter les conflits avec les mots-clés de Python." Elle précise également qu'"il est généralement préférable d'ajouter un seul trait de soulignement à la fin plutôt que d'utiliser une abréviation ou une faute d'orthographe". Ainsi, list_ est meilleur que lst".
#16 Les soulignés en tête
class Example:
def __init__(self):
self._internal = 2
self.external = 20
Vous constaterez souvent que les programmeurs Python expérimentés ont tendance à préfixer un trait de soulignement à un identifiant ou à un nom de méthode - et ce pour de bonnes raisons.
Le trait de soulignement préfixé à un identifiant ou à une méthode a une signification cachée : cette variable ou cette méthode est uniquement destinée à un usage interne. Il s'agit essentiellement d'une clause de non-responsabilité à l'égard des autres programmeurs qui a été définie dans la PEP 8, mais qui n'est pas appliquée par Python. Les caractères de soulignement sont donc un indicateur faible.
Contrairement à Java, Python ne fait pas de distinction très nette entre les variables privées et les variables publiques. En d'autres termes, il n'a de sens que parce que la communauté Python a accepté qu'il en ait un. Leur inclusion n'a pas d'impact sur le comportement de vos programmes.
#17 Underscore Visual
Voici le dernier conseil sur les traits de soulignement ; Jusqu'à présent, nous avons couvert trois cas d'utilisation différents du trait de soulignement, mais vous pouvez consulter notre tutoriel pour en savoir plus sur le rôle du trait de soulignement(_) dans Python.
number = 1_500_000
print(number)
"""
15000000
"""
Le trait de soulignement peut également être utilisé comme séparateur visuel pour le regroupement de chiffres dans les nombres intégraux, flottants et complexes. Cette fonction a été introduite dans Python 3.6.
L'idée était d'améliorer la lisibilité des littéraux longs, ou des littéraux dont la valeur doit être clairement séparée en plusieurs parties - vous pouvez en savoir plus à ce sujet dans le PEP 515.
#18 __name__ == “__main__”
if __name__ == "__main__":
print("Read on to understand what is going on when you do this.")
"""
print("Read on to understand what is going on when you do this.")
"""
Il y a de fortes chances que vous ayez vu cette syntaxe dans plusieurs programmes Python ; Python utilise un nom spécial appelé "__main__" et lui attribue un identifiant appelé __name__ si le fichier Python en cours d'exécution est le programme principal.
Si nous décidons d'importer le module affiché dans la capture d'écran dans un autre module (fichier Python) et d'exécuter ce fichier, la vérité de l'expression dans notre code sera fausse. En effet, lorsque nous importons d'un autre module, l'identifiant __name__ est remplacé par le nom du module (fichier Python).
#19 La méthode "setdefault
import pprint
text = "It's the first of April. It's still cold in the UK. But I'm going to the museum so it should be a wonderful day"
counts = {}
for word in text.split():
counts.setdefault(word, 0)
counts[word] += 1
pprint.pprint(counts)
"""
{'April.': 1,
'But': 1,
"I'm": 1,
"It's": 2,
'UK.': 1,
'a': 1,
'be': 1,
'cold': 1,
'day': 1,
'first': 1,
'going': 1,
'in': 1,
'it': 1,
'museum': 1,
'of': 1,
'should': 1,
'so': 1,
'still': 1,
'the': 3,
'to': 1,
'wonderful': 1}
"
Vous pouvez souhaiter définir une valeur pour différentes clés d'un dictionnaire. Par exemple, lorsque vous faites le cursus du nombre de mots dans un corpus. La façon la plus courante de procéder est la suivante :
- Vérifier si la clé existe dans le dictionnaire
- Si c'est le cas, la valeur est incrémentée de 1.
- Si ce n'est pas le cas, ajoutez-la et fixez la valeur à 1.
Voici à quoi cela ressemble dans le code :
counts = {}
for word in text.split():
if word in counts:
counts[word] += 1
else:
counts[word] = 1
Une façon plus concise de procéder consiste à utiliser la méthode setdefault() sur votre objet dictionnaire.
Le premier argument transmis à la méthode est la clé que nous voulons vérifier. Le deuxième argument transmis est la valeur à attribuer à la clé si celle-ci n'existe pas encore dans le dictionnaire - si la clé existe, la méthode renvoie la valeur de la clé. Il ne sera donc pas modifié.
#20 Correspondance des expressions rationnelles
import re
number = re.compile(r"(0?)(\+44)?\d(10)")
num_1 = number.search("My number is +447999999999")
num_2 = number.search("My number is 07999999999")
print(num_1.group())
print(num_2.group())
"""
'+447999999999'
'07999999999'
"""
Les expressions régulières vous permettent de spécifier un modèle de texte à rechercher ; la plupart des gens savent que nous pouvons rechercher des choses en utilisant CTRL + F (Windows), mais si vous ne connaissez pas la chose exacte que vous recherchez, comment pouvez-vous la trouver ? La réponse consiste à rechercher des modèles.
Par exemple, les numéros britanniques suivent un schéma similaire : ils comportent un zéro au début et dix chiffres ou +44 au lieu de zéro et dix chiffres - la deuxième occurrence indique qu'il s'agit du format international.
Les expressions régulières permettent de gagner beaucoup de temps. Si nous devions coder des règles pour attraper les instances dans notre image au lieu d'utiliser des expressions rationnelles, cela pourrait prendre jusqu'à plus de 10 lignes de code.
Il est essentiel d'apprendre comment fonctionnent les expressions régulières, même si vous n'écrivez pas de code. La plupart des éditeurs de texte et des traitements de texte modernes vous permettent d'utiliser des expressions régulières pour rechercher et remplacer des éléments.
#21 Regex Pipe
import re
heros = re.compile(r"Super(man|woman|human)")
h1 = heros.search("This will find Superman")
h2 = heros.search("This will find Superwoman")
h3 = heros.search("This will find Superhuman")
print(h1.group())
print(h2.group())
print(h3.group())
"""
Superman
Superwoman
Superhuman
"""
Les expressions régulières comportent un caractère spécial appelé pipe(|) qui vous permet de faire correspondre une expression parmi d'autres, et elles peuvent être utilisées n'importe où. C'est très pratique lorsque vous avez plusieurs modèles similaires.
Par exemple, "Superman", "Superwoman" et "Superhuman" ont tous le même préfixe. Ainsi, vous pouvez utiliser le tuyau pour conserver la partie du modèle qui est récurrente et modifier les parties dont vous avez besoin pour être différent. Une fois de plus, vous gagnez un temps précieux.
Attention au piège: si toutes les expressions que vous souhaitez faire correspondre se trouvent dans le même texte, la première occurrence du texte à faire correspondre sera renvoyée - par exemple, "Un exemple de texte contenant Superwoman, Superman, Superhuman" renverra Superwoman.
#22 Le paramètre 'sep' de la fonction d'impression
day = "04"
month = "10"
year = "2022"
print(day, month, year)
print(day, month, year, sep = "")
print(day, month, year, sep = ".")
"""
04 10 2022
04/10/2022
04.10.2022
"""
Le nombre de programmeurs Python qui ne connaissent pas toutes les capacités de la fonction print() est effrayant. Si "Hello World" a été votre premier programme, la fonction print() a probablement été l'une des premières fonctions intégrées que vous avez abordées lorsque vous avez appris Python. Nous utilisons print() pour afficher des messages formatés à l'écran, mais la fonction print() a bien d'autres fonctions.
Dans le code ci-dessus, nous avons montré différentes façons d'afficher notre message formaté. Le paramètre sep est un argument facultatif de la fonction print() qui nous permet de spécifier comment les objets doivent être séparés si nous en incluons plusieurs.
Par défaut, ils sont séparés par un espace, mais nous avons modifié cette fonctionnalité avec nos instructions d'impression - l'une où sep est défini à "" et l'autre où sep est défini à ".".
#23 Fonctions Lambda
def square(num:int) -> int:
return num ** 2
print(f"Function call: {square(4)}")
"""
Function call: 16
"""
square_lambda = lambda x: x**2
print(f"Lambda function: {square_lambda(4)}")
"""
Lambda functional: 16
"""
Les fonctions lambda vous amènent à des choses de niveau plus intermédiaire-avancé que vous pourriez faire avec Python - apprenez Python intermédiaire avec ce cours. Ils semblent compliqués à première vue, mais ils sont très simples.
Dans notre exemple de code, nous n'avons utilisé qu'un seul argument, mais nous aurions pu en utiliser plusieurs si nous l'avions voulu :
square = lambda a, b: a ** b
print(f"Lambda function: {square(4, 2)}")
"""
16
"""
Essentiellement, le mot-clé lambda nous permet de créer de petites fonctions anonymes restreintes en une seule ligne. Elles se comportent comme une fonction normale déclarée avec le mot-clé def, sauf qu'elles n'ont pas de nom.
#24 La méthode "swapcase
string = "SoMe RaNDoM sTriNg"
print(string.swapcase())
"""
sOmE rAndOm StRInG
"""
La méthode swapcase() est appliquée à un objet de type chaîne de caractères pour nous permettre de changer les majuscules en minuscules et vice versa en une seule ligne de code. Les cas d'utilisation de la méthode swapcase() ne sont pas nombreux, mais il est bon de le savoir.
#25 La méthode "isalnum
password = "ABCabc123"
print(password.isalnum())
"""
True
"""
Supposons que nous créions un programme qui demande aux utilisateurs d'entrer un mot de passe, mais qui doit comporter une combinaison de chiffres et de lettres. Nous pouvons le faire en une ligne de code en appelant la fonction isalnum() sur l'instance de chaîne.
La méthode vérifie si tous les caractères font partie de l'alphabet (A-Za-z) et des chiffres (0-9). Un espace ou un symbole (!#%$& ? etc.) renvoie la réponse suivante Faux.
#26 Traitement des exceptions
def get_ration(x:int, y:int) -> int:
try:
ratio = x/y
except: ZeroDivisionError:
y = y + 1
ratio = x/y
return ratio
print(get_ratio(x=400, y=0))
"""
400.0
"""
Les programmes Python se terminent lorsqu'ils rencontrent une erreur.
Parfois, nous ne voulons pas de ce comportement, par exemple lorsqu'un utilisateur final interagit avec notre code. Quel mal y aurait-il à ce que notre code se termine prématurément dans un tel cas ?
Il existe plusieurs façons de traiter les cas exceptionnels. La plupart des programmeurs Python adhèrent généralement à l'idée qu'il est plus facile de demander le pardon que d'obtenir la permission. Cela signifie qu'ils préfèrent attraper une erreur en fournissant un contexte environnant capable de gérer une exception. L'idée qui sous-tend cette réflexion est qu'il est inutile de perdre du temps à essayer de se prémunir contre tous les cas exceptionnels.
Mais cela ne vaut que s'il existe un mécanisme permettant de faire face à un problème une fois qu'il s'est produit.
#27 Identifier les différences dans les listes
list_1 = [1, 3, 5, 7, 8]
list_2 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
solution_1 = list(set(list_2) - set(list_1))
solution_2 = list(set(list_1) ^ set(list_2))
solution_3 = list(set(list_1).symmetric_difference(set(list_2)))
print(f"Solution 1: {solution_1}")
print(f"Solution 2: {solution_2}")
print(f"Solution 3: {solution_3}")
"""
Solution 1: [9, 2, 4, 6]
Solution 2: [2, 4, 6, 9]
Solution 3: [2, 4, 6, 9]
"""
Voici trois méthodes différentes pour comparer la différence entre deux listes en Python.
Note: À moins que vous ne sachiez avec certitude que list_1 est un sous-ensemble de list_2, la solution 1 n'est pas la même que les deux autres solutions.
#28 Args & Kwargs
def some_function(*args, **kwargs):
print(f"Args: {args}")
print(f"Kwargs: {kwargs}")
some_function(1, 2, 3, a=4, b=5, c=6)
"""
Args: (1, 2, 3)
Kwargs: {'a': 4, 'b': 5, 'c': 6}
"""
Nous utilisons *args et **kwargs comme paramètres d'une fonction lorsque nous ne connaissons pas le nombre de variables que notre fonction devrait attendre.
Le paramètre *args nous permet de passer un nombre variable de paramètres à une fonction lorsqu'elle n'a pas de mot-clé (c'est-à-dire que les paramètres que nous passons n'ont pas besoin d'un nom associé). D'autre part, le paramètre **kwargs nous permet de passer un nombre arbitraire de paramètres à une fonction.
En réalité, les mots *args et **kwargs ne sont pas si magiques que cela : la véritable magie réside dans les astérisques (*). Cela signifie que nous aurions pu utiliser n'importe quel mot après les astérisques, mais l'utilisation d'args et de kwargs est une pratique courante, et elle est appliquée par les développeurs de Python.
#29 L'ellipse
print(...)
"""
Ellipsis
"""
def some_function():
...
# Alternative solution
def another_function():
pass
L'ellipse est un objet Python qui peut être appelé en fournissant une séquence de trois points (...) ou en appelant l'objet lui-même (Ellipsis).
Son utilisation la plus notable est l'accès et le découpage de tableaux multidimensionnels dans NumPy, par exemple :
import numpy as np
arr = np.array([[2,3], [1,2], [9,8]])
print(arr[...,0])
"""
[2 1 9]
"""
print(arr[...])
"""
[[2 3]
[1 2]
[9 8]]
"""
Mais l'ellipse peut également être utilisée comme espace réservé dans une fonction non implémentée.
Cela signifie que vous pouvez passer Ellipsis, ..., ou passer, et qu'ils resteront tous valables.
#30 Compréhension des listes
even_numbers = [x for x in range(10) if x % 2 == 0 and x != 0]
print(even_numbers)
"""
[2, 4, 6, 8]
"""
Notre dernière astuce Python concerne les compréhensions de liste, une manière élégante de créer une liste à partir d'une autre séquence. Ils vous permettent d'effectuer des opérations logiques et de filtrage sophistiquées, comme nous l'avons fait dans le code ci-dessus.
Il existe d'autres moyens d'atteindre le même objectif ; par exemple, nous aurions pu utiliser une fonction lambda comme suit :
even_numbers = list(filter(lambda x: x % 2 ==0 and x != 0, range(10)))
print(even_numbers)
"""
[0, 2, 4, 6, 8]
"""
Mais plusieurs Pythonistes soutiendraient que cette solution est beaucoup moins lisible que la compréhension de la liste.
Consultez ce tutoriel pour en savoir plus sur les compréhensions de listes en Python.
Les meilleurs cours de Python
cours
Écrire des fonctions en Python
cours