Python est facile à écrire et à comprendre, mais tu peux rapidement l’utiliser de la mauvaise manière et te retrouver dans un champ de mines antipersonnel.
Cet article dresse une liste de 21 astuces concises qui amélioreront la lisibilité et l’efficacité de ton code. Ces conseils sont tirés de projets persos, de revues de code et de discussions inspirantes avec des dévs.
Que tu sois nouveau dans le langage Python ou déjà un développeur expérimenté, cet article devrait te permettre d’apprendre quelques petites choses.
Cette liste comprend des modèles communs à Python, des concepts de base et certaines des meilleures pratiques.
Comme les 21 astuces n’ont pas d’ordre prédéfini, n’hésite pas à passer directement aux sections qui t’intéressent.
Sans plus attendre, jetons un coup d’œil 👀
#1 – Opérateurs ternaires
Les opérateurs ternaires en Python permettent d’écrire des expressions conditionnelles en ligne. Ils sont particulièrement utiles lorsque tu dois affecter une valeur à une variable en fonction d’une condition.
age = 25 status = "Adulte" if age >= 18 else "Mineur" print(status) # Adulte
Dans cet exemple, la valeur de la variable status sera “Adulte” si age
est supérieur ou égal à 18, sinon ce sera “Mineur”.
Les opérateurs ternaires sont utiles lorsqu’ils sont utilisés dans une compréhension de liste :
scores = [100, 46, 54, 23, 20, 99] threshold = 50 results = ["admis" if score > threshold else "non admis" for score in scores] print(results) # ['admis', 'non admis', 'admis', 'non admis', 'non admis', 'admis']
ou dans des fonctions lambda :
scores = [100, 46, 54, 23, 20, 99] threshold = 50 results = map(lambda score: "admis" if score > threshold else "non admis", scores) print(results) # ['admis', 'non admis', 'admis', 'non admis', 'non admis', 'admis']
#2 – Gestionnaires de contexte
Imagine que tu ouvres un fichier avec Python, que tu y écrives quelques lignes, puis qu’une exception se produise avant même que tu ne puisses le fermer.
Bien que cela ne semble pas être un problème pour un développeur débutant, cette situation maintient en mémoire une ressource qui n’est jamais nettoyée (un descripteur de fichier) et peut empêcher l’écriture d’une partie des données.
Les gestionnaires de contexte permettent d’éviter cela. Ils sont utilisés pour gérer les ressources et s’assurer qu’elles sont correctement initialisées et nettoyées.
Ils permettent d’écrire un code plus lisible et plus facile à maintenir en encapsulant la logique de gestion des ressources dans l’objet gestionnaire de contexte.
👉 Le gestionnaire de contexte le plus courant est celui que tu crées avec open
with open('file.txt', 'r') as file: # si un problème survient ici data = file.read()
La fonction open()
renvoie un objet fichier qui agit comme un gestionnaire de contexte. Il ferme automatiquement le fichier lorsque le bloc à l’intérieur de l’instruction with
est quitté, assurant ainsi un nettoyage adéquat.
Tu peux également utiliser des gestionnaires de contexte dans d’autres situations :
👉 Connexions à une base de données :
with psycopg2.connect(database='mydb') as conn: cursor = conn.cursor() cursor.execute('SELECT * FROM table') results = cursor.fetchall()
Dans cet exemple, la méthode connect()
de la bibliothèque psycopg2
renvoie un objet de connexion qui agit comme un gestionnaire de contexte qui ferme automatiquement la connexion lorsque le bloc est quitté.
👉 Ressources de verrouillage :
import threading lock = threading.Lock() def some_function(): with lock: # Section critique du code
Ici, l’objet Lock()
du module de threading est utilisé comme gestionnaire de contexte pour garantir qu’un seul thread peut accéder à la section critique du code à la fois.
#3 – Création de ses propres gestionnaires de contexte !
Il peut arriver que tu doives définir ton propre gestionnaire de contexte.
Pour ce faire, tu dois définir une classe qui implémente les méthodes __enter__()
et __exit__()
:
- __
enter__()
est appelée lorsque l’exécution est lancée avec le blocwith
__exit__()
est appelée lorsque l’exécution quitte le bloc de codewith
Voici un exemple de gestionnaire de contexte personnalisé qui mesure le temps d’exécution d’un bloc de code :
Exemple 1 : Un timer
import time class Timer: def __enter__(self): self.start_time = time.time() def __exit__(self, exc_type, exc_val, exc_tb): elapsed_time = time.time() - self.start_time print(f"Durée d'exécution : {elapsed_time} secondes")
Cet exemple est assez simple. Examinons-en un autre pour imiter le comportement d’open
.
Exemple 2 : Un ouvreur de fichiers personnalisé
class WritableFile: def __init__(self, file_path): self.file_path = file_path def __enter__(self): print("ouverture d'un fichier") self.file_obj = open(self.file_path, mode="w") return self.file_obj def __exit__(self, exc_type, exc_val, exc_tb): if self.file_obj: self.file_obj.close() print("fichier fermé avec succès) # f correspond à ce que la méthode __enter__ renvoie with WritableFile("./test.txt") as f: pass
Bien que ces exemples soient assez simples, ils devraient te donner un exemple de code de départ pour construire des gestionnaires de contexte plus avancés où le nettoyage des ressources est effectué de manière appropriée.
#4 – Enumerate
Si tu souhaites itérer sur une séquence tout en gardant une trace de l’index de chaque élément, tu dois utiliser la fonction enumerate
.
Elle rend le code plus concis en éliminant la nécessité de gérer manuellement une variable d’index distincte.
fruits = ['pomme', 'banane', 'orange'] for index, fruit in enumerate(fruits): print(f"Index : {index}, Fruit : {fruit}") # Index : 0, Fruit : pomme # Index : 1, Fruit : banane # Index : 2, Fruit : orange
#5 – Zip
La fonction zip
permet d’itérer sur plusieurs séquences simultanément :
names = ['Alice', 'Bob', 'Charlie'] ages = [25, 30, 35] for name, age in zip(names, ages): print(f"Prénom : {name}, Âge : {age}") # Prénom : Alice, Âge : 25 # Prénom : Bob, Âge : 30 # Prénom : Charlie, Âge : 35
Dans un cas d’utilisation intéressant, zip
peut également créer un dictionnaire à partir de deux listes, où les clés proviennent de la première liste et les valeurs de la seconde.
keys = ['a', 'b', 'c'] values = [1, 2, 3] my_dict = dict(zip(keys, values)) print(my_dict) # {'a': 1, 'b': 2, 'c': 3}
#6 – Trier des objets complexes avec sorted
La fonction sorted
permet de trier des objets complexes en fonction de certains de leurs attributs.
Pour accéder à la valeur de l’attribut à trier, tu dois utiliser une fonction clé personnalisée.
Supposons que tu souhaites classer ces personnes en fonction de la clé “age”.
people = [ {'name': 'Alice', 'age': 25}, {'name': 'Bob', 'age': 30}, {'name': 'Charlie', 'age': 20} ]
Il suffit de définir l’argument clé pour qu’il pointe vers les valeurs d’âge.
sorted_people = sorted(people, key=lambda x: x['age']) print(sorted_people) # [{'name': 'Charlie', 'age': 20}, {'name': 'Alice', 'age': 25}, {'name': 'Bob', 'age': 30}]
Il en va de même si les dictionnaires sont remplacés par des objets :
class Person: def __init__(self, name, age): self.name = name self.age = age people = [ Person('Alice', 25), Person('Bob', 30), Person('Charlie', 20) ] sorted_people = sorted(people, key=lambda x: x.age) print([person.name for person in sorted_people]) print(sorted_people) # ['Charlie', 'Alice', 'Bob']
#7 – Économiser de la mémoire avec les générateurs
Les générateurs Python sont un type d’itérable qui peut être utilisé pour générer une séquence de valeurs à la volée, sans les stocker toutes en mémoire en même temps. Ils sont définis en utilisant le mot-clé yield
au lieu de return
.
Voici un générateur simple qui calcule les nombres de Fibonacci.
def fibonacci_generator(): a, b = 0, 1 while True: yield a a, b = b, a + b
L’appel de cette fonction ne l’exécute pas réellement. Elle crée et renvoie plutôt un objet generator.
fib = fibonacci_generator() fib # <generator object fibonacci_generator at 0x7fea39c31890>
Cet objet générateur ne génère des valeurs de Fibonacci que lorsqu’il est transmis à la fonction next
.
next(fb) # 0 next(fb) # 1 next(fb) # 1 next(fb) # 2
Ou itérée à l’aide d’une boucle for (qui appelle en fait la fonction suivante sous le capot).
Cette méthode est économe en mémoire car elle évite de générer la totalité de la séquence (infinie) en amont.
Un cas d’utilisation naturel des générateurs est la lecture d’un grand ensemble de données ligne par ligne (ou morceau par morceau).
def read_large_file(filename): with open(filename, 'r') as file: for line in file: yield line file_generator = read_large_file('large_file.txt') # traiter ligne par ligne au lieu de charger le fichier complet for line in file_generator: process_line(line) # Traitement
#8 – Améliorez le formatage des chaînes de caractères avec les f-strings !
Les f-strings améliorent la syntaxe de formatage des chaînes : il s’agit de chaînes littérales avec un f
au début et des accolades contenant des expressions qui seront remplacées par leurs valeurs.
La syntaxe est assez simple.
name = "Alice" age = 25 print(f"Hello {name}, tu as {age} ans !") # Hello Alice, tu as 25 ans!
Tu peux même l’utiliser pour évaluer des expressions arbitraires, telles que des appels de fonction :
def add_numbers(a, b): return a + b x = 5 y = 3 print(f"La somme de {x} et {y} est {add_numbers(x, y)}.") # Output: La somme de 5 et 3 est 8.
Des flottants avec une précision particulière :
pi = 3.14159265359 print(f"La valeur de pi est approximativement {pi:.2f}.") # Output: La valeur de pi est approximativement 3.14.
Objets.
class Person: def __init__(self, name, age): self.name = name self.age = age person = Person("Bob", 25) print(f"Prénom : {person.name}, Âge : {person.age}") # Output: Prénom : Bob, Âge : 25
Dictionnaires (guillemets simples autour des clés du dictionnaire) :
>>> data_scientist = {'name': 'Rod PARIS', 'age': 35} >>> f"Ce data scientist est {data_scientist['name']}, âgé de {data_scientist['age']} ans." Ce data scientist est Rod PARIS, agé de 35 ans.
#9 – Construire des objets itérables en utilisant le protocole iterator
Est-ce que tu t’es déjà demandé comment les simples boucles for fonctionnent en coulisses ?
La réponse ne se trouve pas dans la boucle for elle-même, mais plutôt dans les objets qui sont itérés (c’est-à-dire les itérables). Il peut s’agir de listes, de dicts ou d’ensembles.
En fait, les itérables supportent le protocole itérateur et implémentent les méthodes dunder __iter__()
et __next()__
.
Ces méthodes sont les méthodes de base qui permettent d’itérer sur une collection d’éléments ou d’effectuer des itérations personnalisées.
Voici un itérateur personnalisé qui prend une liste de nombres et génère leurs carrés à la volée :
class SquareIterator: def __init__(self, numbers): self.numbers = numbers self.index = 0 def __iter__(self): return self def __next__(self): if self.index >= len(self.numbers): raise StopIteration square = self.numbers[self.index] ** 2 self.index += 1 return square
- La méthode
__iter__()
renvoie l’objet iterator lui-même. Cette méthode est appelée lorsque l’itérateur est initialisé. - Dans la méthode
__next__()
, définis la logique de récupération de l’élément suivant dans l’itération. Cette méthode doit lever l’exceptionStopIteration
lorsqu’il n’y a plus d’éléments à itérer. (remarque que l’index est incrémenté à cet ensemble pour garder une trace de sa position)
Nous pouvons utiliser cet itérateur personnalisé comme suit :
numbers = [1, 2, 3, 4, 5] iterator = SquareIterator(numbers) for square in iterator: print(square) # 1 # 4 # 9 # 16 # 25
#10 – Créer des classes d’exceptions personnalisées pour documenter ton code
Je n’ai jamais pensé à créer des classes d’exception personnalisées. Je me suis contenté des classes intégrées.
En réalité, le fait d’avoir des classes d’exception dans une base de code importante présente de nombreux avantages.
- Elles te permettent de créer des exceptions plus spécifiques et plus significatives qui représentent avec précision l’erreur ou la condition exceptionnelle qui se produit dans ton code. Cela facilite le débogage.
- Elles améliorent la collaboration : si tes collègues commencent à pousser du code dans le même repo, il est plus facile pour eux de déboguer l’erreur avec un message explicite plutôt que d’avoir une exception
ValueError
générique.
Voici un exemple de classe d’exception personnalisée qui est levée lorsqu’une chaîne d’entrée est plus longue qu’une valeur seuil.
class NameTooLongError(Exception): """Custom exception for names that are too long.""" def __init__(self, name, max_length): self.name = name self.max_length = max_length super().__init__(f"Name '{name}' est trop long. La longueur maximale autorisée est de {max_length} caractères.") def process_name(name): max_length = 10 # Maximum allowed name length if len(name) > max_length: raise NameTooLongError(name, max_length) else: print("Traitement du nom réussi :, name) # Example usage try: input_name = "AVeryLongName" process_name(input_name) except NameTooLongError as e: print("Error:", e)
#11 – setattr et getattr pour interagir dynamiquement avec les classes
Les méthodes setattr
et getattr
de Python sont des fonctions intégrées qui permettent de définir et d’obtenir dynamiquement les attributs d’un objet, respectivement.
setattr
:
– setattr(obj, name, value)
définit l’attribut name
de l’objet obj
à la valeur donnée.
Si l’attribut n’existe pas, setattr
crée un nouvel attribut.
class Person: pass person = Person() setattr(person, "name", "John") setattr(person, "age", 25) print(person.name) # John print(person.age) # 25
Si tu essayes d’accéder à un attribut inexistant, tu obtiendras une erreur de type AttributeError
.
print(getattr(person, "address")) --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Input In [26], in <cell line: 8>() 6 print(getattr(person, "name")) # Output: John 7 print(getattr(person, "age")) # Output: 25 ----> 8 print(getattr(person, "address")) # Output: AttributeError 9 print(getattr(person, "address", "N/A")) AttributeError: 'Person' object has no attribute 'address'
Pour éviter ce problème, il convient de fournir une valeur par défaut :
print(getattr(person, "address", "N/A")) # N/A
#12 – Le véritable objectif de l’underscore
As-tu déjà vu des traits de soulignement (_
) utilisés dans du code Python ?
Il y a peut-être une raison à cela.
En Python, les underscores sont des variables spéciales qui sont utilisées comme des espaces réservés pour des valeurs inutiles ou ignorées.
Voici quelques exemples d’utilisation des caractères de soulignement :
✅ Ignorer une valeur lors de l’unpacking :
_, age, _ = ("John", 25, "USA") print(age) # Output: 25
✅ Suppression d’une variable de boucle :
numbers = [1, 2, 3, 4, 5] for _ in numbers: print("Bouclage...")
✅ Ignorer les valeurs de retour des fonctions :
def calculate_values(): # ... quelques calculs ... return result1, result2, result3 _, important_result, _ = calculate_values()
✅ Placeholder dans les arguments de fonction non utilisés :
def process_data(data, _): # ... traitement dess données ... process_data(my_data, _)
#13 – Un aperçu de la programmation fonctionnelle avec map, filter et reduce
map
, filter
et reduce
sont des fonctions intégrées à Python qui opèrent sur des itérables.
👉 map
La fonction map
applique une fonction donnée (premier argument) à chaque élément d’une table itérative (deuxième argument) et renvoie un itérateur avec les résultats.
numbers = [1, 2, 3, 4, 5] squared_numbers = map(lambda x: x**2, numbers) print(list(squared_numbers)) # [1, 4, 9, 16, 25]
C’est l’équivalent exact de l’extrait de code suivant :
numbers = [1, 2, 3, 4, 5] squared_numbers = [] for number in numbers: squared_numbers.append(number ** 2) print(squared_numbers) # [1, 4, 9, 16, 25]
👉 filter
La fonction filter
crée un itérateur qui filtre les éléments d’un itérable (deuxième argument) en fonction d’une condition donnée (premier argument).
numbers = [1, 2, 3, 4, 5] even_numbers = filter(lambda x: x % 2 == 0, numbers) print(list(even_numbers)) # [2, 4]
C’est l’équivalent exact de l’extrait de code suivant :
numbers = [1, 2, 3, 4, 5] even_numbers = [] for number in numbers: if number % 2 == 0: even_numbers.append(number) print(even_numbers) # [2, 4]
👉 reduce
La fonction reduce
applique une fonction donnée aux éléments d’un itérable de manière cumulative, en les réduisant à une valeur unique.
from functools import reduce numbers = [1, 2, 3, 4, 5] sum_of_numbers = reduce(lambda x, y: x + y, numbers) print(sum_of_numbers) # 15
#14 – Décomposition de séquences (et échange de variables)
Le déballage de variables en Python vous permet d’assigner plusieurs valeurs d’un itérable à plusieurs variables en une seule ligne.
Tu peux l’utiliser pour échanger des variables :
a = 10 b = 20 a, b = b, a print(a, b) # 20 10
Déballer des tuples ou des listes :
point = (3, 4) x, y = point print(x, y) # 3 4
ou les valeurs de retour des fonctions :
def get_name(): return "John", "Doe" first_name, last_name = get_name() print(first_name, last_name) # John Doe
#15 – Compter les itérables avec Counter
Tu peux compter les objets hachables en utilisant la classe collections.Counter
en Python.
from collections import Counter my_list = [1, 2, 3, 2, 1, 3, 4, 5, 1] count = Counter(my_list) print(count) # Counter({1: 3, 2: 2, 3: 2, 4: 1, 5: 1})
Le fait de disposer d’un objet Counter
te permet d’accéder à des méthodes utiles telles que most_common
, qui produit une liste de tuples dont le premier élément est une valeur et le second son nombre.
count.most_common(2) # [(1, 3), (2, 2)]
#16 – Représentation des chaînes d’objets avec __str__ et __repr__
Les méthodes __str__
et __repr__
de Python sont utilisées pour fournir des représentations sous forme de chaîne de caractères d’un objet. La principale différence entre elles est leur objectif et le public auquel elles s’adressent.
Commençons par la classe suivante :
class Person(object): def __init__(self, first_name, last_name, age): self.first_name = first_name self.last_name = last_name self.age = age person = Person("john", "does", 30) print(person) # <__main__.Person object at 0x7fea39945b20>
Note que l’impression de l’objet ne donne pas une belle représentation. Au lieu de cela, elle montre l’adresse mémoire qui lui a été allouée.
- La méthode
__str__
peut modifier ce comportement :
class Person(object): def __init__(self, first_name, last_name, age): self.first_name = first_name self.last_name = last_name self.age = age def __str__(self): return f"{self.first_name} {self.last_name} ({self.age})" person = Person("john", "does", 30) print(person) # john does (30)
Cependant, si tu inspectes cet objet à partir de l’interpréteur de code, tu obtiendras le formatage précédent :
person <__main__.Person at 0x7fea399ca3d0>
Pour éviter cela, tu dois implémenter la méthode __repr__
:
class Person(object): def __init__(self, first_name, last_name, age): self.first_name = first_name self.last_name = last_name self.age = age def __repr__(self): return f"{self.first_name} {self.last_name} ({self.age})" person = Person("john", "does", 30) # john does (30)
Maintenant, si tu veux imprimer cet objet, tu obtiendras le même formatage agréable.
print(person) # john does (30)
Ce que j’en retiens est simple :
__str__
et__repr__
contrôlent la représentation des chaînes de caractères- tu peux ajouter une méthode
__repr__
à tes classes, car l’implémentation de__str__
la prendra par défaut.
#17 – Utilisation de groupby dans itertools
Lorsque tu souhaites regrouper un itérable par clé, tu peux utiliser la fonction groupby
de la bibliothèque intégrée itertools
.
Considérons la forme la plus simple des itérables : une chaîne de caractères (une string).
from itertools import groupby code = "BBEDBACEAEBACBDEDACC" grouped = groupby(code, key=None) for key, group in grouped: print(f"key: {key} | group : {list(group)}") # key: B | group : ['B', 'B'] # key: E | group : ['E'] # key: D | group : ['D'] # key: B | group : ['B'] # key: A | group : ['A'] # key: C | group : ['C'] # key: E | group : ['E'] # key: A | group : ['A'] # key: E | group : ['E'] # key: B | group : ['B'] # key: A | group : ['A'] # key: C | group : ['C'] # key: B | group : ['B'] # key: D | group : ['D'] # key: E | group : ['E'] # key: D | group : ['D'] # key: A | group : ['A'] # key: C | group : ['C', 'C']
La fonction groupby
parcourt la chaîne et chaque fois qu’elle voit une séquence de lettres identiques consécutives, elle les regroupe sous une seule touche (la première lettre).
La méthode
groupby
est plus utile lorsque tu trriees l’itérable avant : cela te permettra d’avoir tous les groupes distincts des mêmes éléments.
from itertools import groupby code = "AAAABBBBBCCCCDDDEEEE" grouped = groupby(code, key=None) for key, group in grouped: print(f"key: {key} | group : {list(group)}") # key: A | group : ['A', 'A', 'A', 'A'] # key: B | group : ['B', 'B', 'B', 'B', 'B'] # key: C | group : ['C', 'C', 'C', 'C'] # key: D | group : ['D', 'D', 'D'] # key: E | group : ['E', 'E', 'E', 'E']
Tu peux également utiliser groupby
sur d’autres itérables.
from itertools import groupby workers = [ {'name': 'john', 'department': 'IT'}, {'name': 'joe', 'department': 'finance'}, {'name': 'alice', 'department': 'IT'}, {'name': 'jack', 'department': 'legal'}, {'name': 'meredith', 'department': 'finance'} ] workers = sorted(data, key=lambda d: d["department"]) grouped = groupby(workers, key=lambda d: d["department"]) for key, group in grouped: print(f"key: {key} | group : {list(group)}") # key: IT | group : [{'name': 'john', 'department': 'IT'}, {'name': 'alice', 'department': 'IT'}] # key: finance | group : [{'name': 'joe', 'department': 'finance'}, {'name': 'meredith', 'department': 'finance'}] # key: legal | group : [{'name': 'jack', 'department': 'legal'}]
#18 – Utilisation de la mémoire cache pour optimiser les appels de fonction
Si tu souhaites éviter les appels de fonction inutiles, en particulier si la sortie ne change pas avec les mêmes entrées pendant un certain temps, tu peux utiliser la mise en cache.
La mise en cache permet de stocker le résultat de la fonction et de le réutiliser ultérieurement.
import requests from functools import lru_cache @lru_cache() def fetch_data(url): content = requests.get(url).content return content url = "https://www.bbc.com/news/world-us-canada-66489815" %%time data = fetch_data(url) # CPU times: user 28.2 ms, sys: 16.7 ms, total: 44.9 ms # Wall time: 135 ms %%time data = fetch_data(url) # CPU times: user 4 µs, sys: 0 ns, total: 4 µs # Wall time: 8.11 µs %%time data = fetch_data(url) # CPU times: user 6 µs, sys: 1e+03 ns, total: 7 µs # Wall time: 10 µs
As-tu remarqué le temps d’exécution entre le premier appel et les deux autres ?
#19 – Fonctions lambda
Les fonctions lambda sont des fonctions anonymes qu’il n’est pas nécessaire de lier à un nom.
Par exemple, voici comment définir une fonction lambda pour effectuer une addition :
add = lambda x, y: x + y add(10, 2) # 12
Conceptuellement, cette fonction lambda est l’équivalent d’une fonction normale que tu déclarerais avec le mot-clé def
.
def add(x, y): return x + y
mais écrites en ligne.
Les fonctions lambda ont une valeur de retour implicite et sont utiles lorsque tu les passes en tant qu’arguments à d’autres fonctions. Voici quelques exemples d’utilisation :
- la programmation fonctionnelle avec
map
(fonctionne également avecfilter
etreduce
)
product_names = ["Iphone 15", "iphone 14 ", " iphone 15", "IPHONE 13"] clean_product_names = map(lambda name: name.strip().lower(), product_names) print(list(clean_product_names) # ['iphone 15', 'iphone 14', 'iphone 15', 'iphone 13']
- fonctions clés dans
sorted
employees = [ {"id": 1, "salary": 95000}, {"id": 2, "salary": 123050}, {"id": 3, "salary": 64000}, {"id": 4, "salary": 80000}, {"id": 5, "salary": 45000}, {"id": 6, "salary": 55000}, ] employees_sorted_by_salary = sorted(employees, key=lambda employee: employee["salary"]) print(employees_sorted_by_salary) # [{'id': 5, 'salary': 45000}, # {'id': 6, 'salary': 55000}, # {'id': 3, 'salary': 64000}, # {'id': 4, 'salary': 80000}, # {'id': 1, 'salary': 95000}, # {'id': 2, 'salary': 123050}]
#20 – Utilisation de la chaîne de itertools
Pour fusionner des listes de listes à l’aide de la fonction chain
du module itertools
, tu peux suivre cet exemple de code :
from itertools import chain # Exemples de listes de listes list_of_lists = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] # Fusionner les listes à l'aide d'une chaîne merged_list = list(chain(*list_of_lists)) print(merged_list) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
#21 – Fusionner des dictionnairres avec l’unpacking
Dans Python 3.5 et les versions ultérieures, tu peux utiliser l’unpacking de dictionnaire pour fusionner des dictionnaires.
dict1 = {'a': 1, 'b': 2} dict2 = {'b': 3, 'c': 4} merged_dict = {**dict1, **dict2} print(merged_dict)
Conclusion
Si tu es arrivé jusqu’ici, je te remercie de ta lecture et j’espère que tu as au moins appris une chose ou deux. N’hésite pas à me dire dans les commentaires ci-dessous si tu penses à d’autres astuces Python utiles !