pichegru.net

Physique-Chimie & NSI

Cours complets et originaux de Physique-Chimie & NSI

1-01. Listes & dictionnaires

Les listes et les dictionnaires sont les deux structures de données les plus importantes introduites en classe de Première.

Celles-ci seront utilisées énormément tout au long de la classe de Terminale pour implémenter divers objets abstraits (listes chaînées, piles, files, graphes et arbres).

Ce premier chapitre est un chapitre presque exclusivement de révision.

Les listes

Ce que vous devez déjà savoir

Les listes sont des collections ordonnées et modifiables d’éléments de n’importe quel type, accessibles par leur position (index).

		
		fruits = ['apple', 'banana', 'mango', 'melon', 'peach'] # créer une liste
		
		type(fruits) # → <class 'list'>
		len(fruits) # → nombre d’éléments

		# accéder à un élément
		fruits[0]  # → 'apple (🖐️ premier élément = n°0)
		fruits[2]  # → 'mango'
		fruits[-1] # → 'peach' (dernier élément)
		fruits[-2] # → 'melon' (avant dernier élément)

		# découpage (slicing) de listes
		fruits[1:3]    # → ['banana', 'mango'] (éléments de l'index 1 inclus à 3 exclus)
		fruits[:2]     # → ['apple', 'banana'] (du début jusqu'à l'index 2 exclus)
		fruits[2:]     # → ['mango', 'melon', 'peach'] (de l'index 2 inclus jusqu'à la fin)
		fruits[::2]    # → ['apple', 'mango', 'peach'] (tous les 2 éléments)
		fruits[::-1]   # → ['peach', 'melon', 'mango', 'banana', 'apple'] (ordre inversé)

		# modifier un élément
		fruits[0] = 'orange' # remplace l’élément n°0 par 'orange'
		del fruits[1] # efface l’élément n°1

		# vérifier la présence d'un élément
		'banana' in fruits  # → True
		'kiwi' in fruits    # → False

		# méthodes courantes des listes
		fruits.count('banana')  # → compte le nombre de fois où 'banana' apparaît
		fruits.append('lemon') # ajoute 'lemon' à la fin de la liste
		fruits.extend(['orange', 'grape'])  # ajoute 'orange' et 'grape' à la fin de la liste
		fruits.insert(1, 'orange')  # insère 'orange' en position 1
		fruits.remove('apple')  # supprimme la première occurence de 'apple'
		fruit = fruits.pop(1)  # renvoie l’élément 1 et le supprime de la liste (défaut = 0)
		fruits.clear()  # supprime tous les éléments de la liste
		index = fruits.index('banana')  # → index de la première occurence de 'banana'
		fruits.sort()  # tri les éléments (🖐️ la liste est modifiée)
		fruits.sort(key=str.lower) # tri sans tenir compte de la casse
		fruits.sort(key=len) # tri par longueur des chaînes
		fruits.reverse() # inverse l’ordre des éléments (🖐️ la liste est modifiée)
		fruits2 = fruits.copy() # fruits2 est une copie indépendante de fruits

		# fusionner deux listes
		food = fruits + ["beans", "spinach"] # une nouvelle liste est créée

		# énumérer les éléments
		for f in fruits:
			print(f) # affiche successivement les éléments de la liste

		# énumérer les éléments avec index
		for i, fruit in enumerate(fruits):
			print(f"Index {i}: {fruit}")  # affiche l’index et l’élément

		# filtrer une liste par compréhension
		numbers = [1, 2, 3, 4, 5, 6]
		even_numbers = [x for x in numbers if x % 2 == 0]

		# compréhension de liste avec condition else
		numbers = [1, 2, 3, 4, 5]
		result = ["pair" if x % 2 == 0 else "impair" for x in numbers]

		# appliquer une fonction à chaque élément par compréhension
		numbers = [1, 2, 3, 4, 5]
		squares = [x**2 for x in numbers]

		# création de liste avec multiplication
		zeros = [0] * 5     # → [0, 0, 0, 0, 0]
		repeated = [1, 2] * 3  # → [1, 2, 1, 2, 1, 2]

		# conversion d’autres types en liste
		chars = list("hello")  # → ['h', 'e', 'l', 'l', 'o']
		tuple_to_list = list((1, 2, 3))  # → [1, 2, 3]
		
	

Passage par référence

Lisez le code ci-dessous :

		
		a = [1,2]
		b = a
		a.append(3)
		print(b) # resultat ?
		
	

Que pensez-vous que la commande print va afficher ? [1,2] ? Eh bien non. Elle va afficher [1,2,3]. Surprenant, n’est-ce pas ? Explications.

À la ligne 1, la liste [1,2] est mise dans un espace mémoire, et le nom a lui est attribué.

À la ligne 2, le nom b est attribué au même espace mémoire que pour la variable a. Ce qui est différent de l’instruction b = [1,2] ! On dit que la valeur de b est passée par référence. Les deux variables a et b pointent vers la même liste. Si on modifie cette liste, comme on le fait à la ligne 3, cela aura un impact sur a et b. Ce comportement est une cause fréquente de bugs lorsqu’on débute.

En Python, les variables contenant des objets mutables (comme les listes et les dictionnaires) sont des références vers ces objets en mémoire, et non des copies indépendantes.
Mais alors, si je veux créer une nouvelle liste indépendante qui est identique à une liste déjà existante, je fais comment ? 😣

La plupart du temps, vous pourrez utiliser la méthode copy(). Cette méthode créer une copie « superficielle » (shallow copy) de votre liste.

		
		fruits = ['apple', 'banana']
		fruits2 = fruits.copy()
		fruits.append('cherry')
		print(fruits2) # ['apple', 'banana']
		
	
Mais pourquoi on appelle ça une copie superficielle ?

Parce que si, dans votre liste, vous avez un élément qui est un objet mutable, cet objet restera le même dans la copie. Compliqué ? 😅 Voici un exemple qui va clarifier ce que je veux dire :

		
		fruits = ['apple', 'banana', [1,2]]
		fruits2 = fruits.copy()
		fruits[2].append(3) # on ajoute 3 à la sous-liste [1,2]
		print(fruits2) # ['apple', 'banana', [1, 2, 3]]
		
	

La liste [1,2] qui est l’élément 2 de la liste fruits reste la même lorsqu’on crée une shallow copy. Donc si vous modifiez cette sous-liste (peu importe comment), ça affectera fruits et fruits2.

Si vous voulez faire une deep copy, il faudra utiliser le module Python copy avec copy.deepcopy().

Les bases

Dans le code ci-dessous, prévoir ce qui va être affiché pour chaque commande print

			
			L = [200, 123, 14, 18, 6, 19]
			print(len(L))
			print(L[0])
			print(L[3])
			print(L[6])

			L[1] = 12
			print(L)
			
		
Correction

Fonction seuil

Le but de cet exercice est de créer la fonction seuil_liste(L: list, val: int|float) qui prend en paramètre une liste numérique L et une valeur numérique val, et renvoie une liste dans laquelle tous les éléments de L ≥ val ont été remplacés par 0. Après exécution de la fonction, la liste L elle-même ne doit pas être pas modifiée.

Pour cet exercice, nous allons utiliser le mot-clé assert.

			
			assert condition, "message d’erreur optionnel"
			
		

À l’exécution, cette ligne lève une AssertionError si la condition est fausse. Pratique pour débuguer un programme. 😊

1. Compléter l’assertion suivante permettant de vérifier que L est bien de type list.

			
			assert isinstance(L, ...), "L n’est pas une liste"
			
		

2. Compléter le code suivant permettant de vérifier que L est une liste de type numérique, c’est-à-dire que tous ses éléments sont de type numériques (int ou float).


		for elem in L:
			assert isinstance(elem, ...) or isinstance(elem, ...), "élément non numérique"
		

3. Écrire la fonction seuil_liste(L: list, val: int|float). Vous devrez vérifier que L est bien de type list et qu’elle ne contient que des nombres (int ou float), et vous devrez vérifier également que val est bien un nombre.


		def seuil_liste(L: list, val: int|float):
			assert isinstance(L, ...), "L n’est pas une liste"
			# écrire le code manquant

			return liste_finale
		
Correction

				def seuil_liste(L, val):
					assert isinstance(L, list), "L n’est pas une liste"
					new_list = []
					for elem in L:
						assert isinstance(elem, (int, float)), "L n’est pas une liste de nombres"
						if elem >= val :
							new_list.append(0)
						else:
							new_list.append(elem)
					return new_list
		

Résultats d’examen

On donne la liste d’élèves suivantes, ainsi que leurs notes à trois épreuves d’examens.

			
			results = [
				["eleve01", [8, 12, 13]],
				["eleve02", ['abs', 10, 7]],
				["eleve03", [15, 18, 19]],
				["eleve04", [14, 'abs', 15]],
				["eleve05", [14, 'abs', 'abs']],
				["eleve06", [10, 10, 11]],
				["eleve07", [12, 8, 8]],
				["eleve08", [13, 15, 11]],
				["eleve09", [14, 15, 16]],
				["eleve10", [12, 13, 12]],
				["eleve11", [9, 11, 12]],
				["eleve12", [16, 16, 14]],
				["eleve13", [10, 'abs', 12]],
				["eleve14", [6, 9, 8]],
				["eleve15", [14, 13, 15]],
				["eleve16", [7, 6, 10]],
				["eleve17", [15, 16, 15]],
				["eleve18", [13, 14, 13]],
				["eleve19", [11, 10, 'abs']],
				["eleve20", [17, 19, 20]],
				["eleve21", [12, 14, 11]],
				["eleve22", [8, 'abs', 9]],
				["eleve23", [15, 12, 13]],
				["eleve24", [9, 7, 10]],
				["eleve25", [16, 13, 'abs']],
				["eleve26", [12, 12, 12]],
				["eleve27", [5, 8, 7]],
				["eleve28", [13, 'abs', 'abs']],
				["eleve29", [18, 17, 16]],
				["eleve30", [11, 12, 14]],
				["eleve31", ['abs', 'abs', 'abs']],
			]
			
		

Écrire la fonction nb_mentions ayant pour paramètres la liste results ainsi qu’un mot-clé pouvant être un des mots suivants exclusivement : recalé, passable, assez bien, bien, très bien. La fonction doit renvoyer le nombre d’élèves ayant la mention correspondant au mot-clé.

  • recalé : moyenne strictement inférieur à 10 ou deux absences.
  • passable : moyenne ≥ 10 et < 12 ou moyen ≥ 10 et une absence (quelle que soit la moyenne).
  • assez bien : moyenne ≥ 12 et < 14.
  • bien : moyenne ≥ 14 et < 16.
  • très bien : moyenne ≥ 16.
Correction

Comme toujours en programmation, il faut découper une tâche « complexe » en plusieurs tâches simple. Commencez par vous posez la question : « quelles sont les différentes opérations simple que je vais devoir intégrer à cette fonction ?

  • Pour un élève donné, calculer sa moyenne, en tenant compte du nombre d’absence. Ceci peut être une première sous-fonction à développer.
  • Pour un élève donné, déterminer le nombre d’absence. Ceci peut être une deuxième sous-fonction.
  • Une fois que les deux sous-fonctions précédentes ont été définies, on peut imaginer une fonction prenant en paramètre un élève et renvoyant sa mention.
  • Enfin, une fois qu’on a les trois sous-fonctions précédentes, on peut écrire notre fonction nb_mentions.

La solution à votre code n’est pas « unique ». Il y a de multiples façons de résoudre ce problème. Gardez seulement en tête qu’un code « de qualité » :

  • Est lisible (le nom des variables et des fonctions est clair et le code est bien structuré, voire commenté).
  • Évite les répétitions inutiles (principe DRY : Don't Repeat Yourself).
  • Est bien découpé en petits éléments indépendants, la tâche de chacun étant simple et bien définie.
  • Reste le plus simple possible pour répondre aux exigences (principe KISS : Keep It Simple, Stupid).

				def get_average(marks):
					"""
					Prend une liste de notes avec éventuellement une ou plusieurs absences
					et renvoie une moyenne (ou None si aucune moyenne ne peut être calculée).
					"""
					numeric_marks = [ mark for mark in marks if isinstance(mark, (int,float)) ]
				
					if len(numeric_marks) == 0:
						return None

					average = sum(numeric_marks) / len(numeric_marks)
					return average

				def get_absences(marks):
					"""Renvoie le nombre d’absences dans une liste de notes"""
					return marks.count("abs")

				def get_mention(student):
					"""Renvoie la mention d’un élève donné"""
					average = get_average(student[1])
					absences = get_absences(student[1])
					if not average or average < 10 or absences >= 2: 
						return "recalé"
					if average >= 10 and average < 12 or absences == 1:
						return "passable"
					if average >= 12 and average < 14:
						return "assez bien"
					if average >= 14 and average < 16:
						return "bien"
					if average >= 16:
						return "très bien"

				def nb_mentions(results, mention):
					counter = 0
					for student in results:
						if get_mention(student) == mention:
							counter += 1
					return counter

				test = nb_mentions(results, "bien")
				print (test)
			

Les dictionnaires

  • Distinguer la recherche d’une valeur dans une liste et dans un dictionnaire.

Ce que vous devez déjà savoir

Les dictionnaires sont des collections de paires clé-valeur, non ordonnées et modifiables

		
		# Dictionnaire vide
		mon_dict = {}

		# Dictionnaire avec des valeurs initiales
		notes_eleves = {"Alice": 15, "Bob": 12, "Charlie": 18}

		# accès aux valeurs
		notes_eleves["Alice"]		# accès direct avec la clé → 15
		notes_eleves["David"]		# lève une KeyError
		notes_eleves.get("David")	# renvoie None
		notes_eleves.get("David", 0)  # Renvoie 0 (valeur par défaut)

		# modification et ajout d’éléments
		notes_eleves["David"] = 14	# ajout
		notes_eleves["Bob"] = 13	# modification

		# suppression d’élément
		del notes_eleves["Charlie"]
		note_bob = notes_eleves.pop("Bob") # suppression et renvoie dans la valeur

		# parcourir un dictionnaire
		for eleve in notes_eleves: # parcourir les clés
			print(f"Élève : {eleve}")

		for eleve in notes_eleves.keys(): # parcourir les clés (explicitement)
			print(f"Élève : {eleve}")

		for note in notes_eleves.values(): # parcourir les valeurs
			print(f"Note : {note}")
		
		for eleve, note in notes_eleves.items(): # parcourir les paires clé-valeur
			print(f"{eleve} a obtenu {note}")

		# vérifier si une clé existe
		if "Alice" in notes_eleves:
			print("Alice est présente dans le dictionnaire")

		# copie d’un dictionnaire.
		# Attention, comme pour les listes, l’affectation simple crée une référence
		notes_copie = notes_eleves.copy()  # Crée une copie superficielle (shallow copy)

		# fusion de dictionnaires
		notes_groupe1 = {"Eva": 16, "Félix": 14}
		notes_groupe2 = {"Gabriel": 11, "Hélène": 19}
		notes_groupe1.update(notes_groupe2)

		# dictionnaires imbriqués
		eleves = {
			"Alice": {"maths": 15, "physique": 17, "français": 14},
			"Bob": {"maths": 12, "physique": 11, "français": 13}
		}
		eleves["Alice"]["physique"] # → 17

		# dictionnaire par compréhension
		carres = {x: x**2 for x in range(1, 6)}
		
	

Recherche dans un dictionnaire

La recherche dans une dictionnaire est un peu plus complexe que dans une liste. Dans une liste, la recherche se fait directement sur les valeurs. Dans un dictionnaire, il faudra faire attention à la notion de clé : valeur. Par défaut, la recherche se fait sur les clés.

		
		# recherche dans une liste
		liste = ["alice", "bob", "charlie"]
		"bob" in liste # → recherche la valeur, renvoie True

		# recherche dans un dictionnaire
		notes_eleves = {"Alice": 15, "Bob": 12, "Charlie": 18}
		eleve = { "prénom" : "Alice", "nom": "Alpha", "age": 17 }
		"Alice" in notes_eleves # → True (la clé "Alice" existe)
		"Alice" in eleve # → False (la clé "Alice" n’existe pas)
		"Alice" in eleve.values() # → True (la valeur "Alice" existe)
		
	

Les bases

Charles possède dans sa ferme cinq lapins, sept vaches, deux cochons et quatre chevaux.

1. Écrire un dictionnaire ferme dans lequel les clés sont les types d’animaux (au singulier) possédés par Charles et les valeurs associées les nombres d’animaux correspondants.

2. Quelle instruction permet d’obtenir le nombre de chevaux que possède Charles ?

3. Charles achète douze poules. Quelle instruction permet de mettre à jour le dictionnaire ferme ?

4. Charles achète six nouveaux lapins. Quelle instruction permet de mettre à jour le dictionnaire ferme ?

5. Ecrire une instruction renvoyant la liste des types d’animaux de la ferme de Charles sous la forme d’une liste.

6. Compléter la fonction suivante grâce à sa documentation.


			def nombre_animaux(ferme):
				'''
				ferme est un dictionnaire dont les clés sont les types d’animaux de la ferme
				et les valeurs associées sont les nombres d’animaux correspondants
				Renvoie le nombre total d’animaux de la ferme
				'''
				nb = ...
				for valeur in ...:
					...
				return nb
		

Les instructions suivantes permettent de tester votre code. Elles ne doivent pas lever d’AssertError lors de leur exécution.

			
				assert nombre_animaux({}) == 0
				assert nombre_animaux({'lapin':5, 'vache':7, 'cochon':2, 'cheval':4}) == 18
				assert nombre_animaux({'lapin':2, 'poule':10, 'âne':4, 'mouton':25}) == 41
				assert nombre_animaux(ferme) == 36
			
		

7. Donner l’instruction permettant d’obtenir le nombre de n’importe quel type d’animaux. Si le dictionnaire ferme ne contient pas cette clé, on doit obtenir 0 (pas d’erreur).

Correction

				ferme = {"lapin": 5, "vache": 7, "cochon": 2, "cheval": 4,}

				print(ferme["cheval"])	# question 2
				ferme["poule"] = 12		# question 3
				ferme["lapin"] = ferme["lapin"] + 6	# question 4
				ferme["lapin"] += 6					# question 4 (autre possiilité)

				# question 5
				liste_animaux_1 = list(ferme) # on convertir le dictionnaire en liste
				print(liste_animaux_1)

				# autre possibilité pour la question 5
				liste_animaux_2 = []
				for animal in ferme :
					liste_animaux_2.append(animal)
					
				print(liste_animaux_2)

				def nombre_animaux(ferme):
					'''
					ferme est un dictionnaire dont les clés sont les types d’animaux de la ferme
					et les valeurs associées sont les nombres d’animaux correspondants
					Renvoie le nombre total d’animaux de la ferme
					'''
					nb = 0
					for valeur in ferme.values():
						nb += valeur
					return nb

				# question 6
				test_1 = ferme["mouton"] # provoque une erreur
				test_2 = ferme.get("mouton", 0) # get renvoie la valeur 0 car "mouton" n’est pas une clé de ferme
				print(test_2)
			

Recettes de cuisines

Voici un exemple de données permettant de manipuler un livre de recettes de cuisine à partir de la liste des ingrédients des recettes :

Recette Ingrédients
Gâteau au chocolat chocolat, oeuf, farine, sucre, beurre
Gâteau au yaourt yaourt, oeuf, farine, sucre
Crêpes oeuf, farine, lait, bière
Quatre-quarts oeuf, farine, beurre, sucre
Kouign-amann farine, beurre, sucre

On va modéliser en Python un livre de recettes par un dictionnaire de type dict[str, list[str]] dans lequel :

  • les noms des recettes, de type str, sont les clés ;
  • l’ensemble des ingrédients, de type list[str], sont les valeurs associées.

1. Construire un dictionnaire LivreRecettes correspondant au tableau ci-dessus.

2. Définir une fonction nb_ingredients qui, à partir d’un dictionnaire de recettes et d’un nom de recette, renvoie le nombre d’ingrédients de cette recette. Par exemple, l’instruction nb_ingredients(LivreRecettes, 'Crêpes') doit renvoyer 4.

3. Définir une fonction recipe_with renvoyant la listes des recettes qui utilisent un ingrédient donné. Par exemple, l’instruction recipe_with(LivreRecettes, 'chocolat') renvoie la liste ['Gâteau au chocolat'].

4. Définir une fonction get_all_ingredients qui renvoie la liste de tous les ingrédients des recettes du livre de recettes passé en paramètre. La liste ne doit pas comporter de doublons.

5. Tout livre de recettes contient une table des ingrédients permettant d’associer à chaque ingrédient l’ensemble des recettes qui l’utilisent. Une telle table sera représentée en Python par le type dict[str, list[str]] dans lequel une clé est un ingrédient dont la valeur associée est la liste des recettes qui l’utilisent. Définir une fonction get_ingredient_table qui, étant donné un livre de recettes D, renvoie la table des ingrédients associée.

6. Écrire la fonction get_main_ingredient qui renvoie l’ingrédient le plus utilisé dans un livre de recettes passé en paramètre. On supposera que le livre de recettes contient au moins une recette. De plus, s’il y a plusieurs ingrédients possibles, on renverra le premier trouvé. Par exemple, get_main_ingredient(LivreRecettes) doit renvoyer 'farine'.

7. Certaines personnes sont allergiques à certains ingrédients. On aimerait donc pouvoir ne conserver d’un livre de recettes que celles qui n’utilisent pas un ingrédient donné. Définir une fonction get_recipe_without qui, étant donné un livre de recettes et un ingrédient passés en paramètre, renvoie un nouveau livre de recettes ne contenant que des recettes n’utilisant pas l’ingrédient donné.

8. Écrire une fonction get_recipe_without_multiple qui, étant donnés un livre de recettes et une liste d’ingrédients passés en paramètres, renvoie un nouveau livre de recettes ne contenant que les recettes n’utilisant aucun des ingrédients donnés.

Correction

				# question 1. Le dictionnaire modélisant le livre de recette
				book = {
					"Gâteau au chocolat" : ["chocolat", "oeuf", "farine", "sucre", "beurre"],
					"Gâteau au yaourt" : ["yaourt", "oeuf", "farine", "sucre"],
					"Crêpes" : ["oeuf", "farine", "lait", "bière"],
					"Quatre-quarts" : ["oeuf", "farine", "beurre", "sucre"],
					"Kouign-amann" : ["farine", "beurre", "sucre"]
				}

				# question 2. nombre d’ingrédients d’une recette donnée
				def nb_ingredients(book, recipe):
					ingredient_list = book.get(recipe, [])
					return len(ingredient_list)

				# question 3. recette utilisant un ingrédient donné
				def recipe_with(book, ingredient):
					recipe_list = []
					for recipe, ingredients in book.items():
						if ingredient in ingredients :
							recipe_list.append(recipe)
					return recipe_list

				# question 4. liste de tous les ingrédients apparaîssant dans le livre
				def get_all_ingredients(book):
					ingredient_list = []
					for ingredients in book.values() :
						for ingredient in ingredients:
							if ingredient not in ingredient_list :
								ingredient_list.append(ingredient)
					return ingredient_list

				# question 5. table des ingrédients
				def get_ingredient_table(book):
					ingredients = get_all_ingredients(book)
					ingredient_table = {}
					for ingredient in ingredients :
						recipe_list = []
						for recipe, recipe_ingredients in book.items():
							if ingredient in recipe_ingredients :
								recipe_list.append(recipe)
						ingredient_table[ingredient] = recipe_list
					return ingredient_table

				# question 6. ingrédient principal
				def get_main_ingredient(book):
					ingredients = get_all_ingredients(book)
					all_ingredients_occurence = []
					max_occurence = 0		 # initialisation
					main_ingredient = ""	 # initialisation
					for recipe_ingredients in book.values():
						all_ingredients_occurence.extend(recipe_ingredients)
						# all_ingredients_occurence contient la liste fusionnée
						# de toutes les listes d’ingrédients des recettes
					for ingredient in ingredients:
						ingredient_occurence = all_ingredients_occurence.count(ingredient) # nombre de recettes avec cet ingrédient
						if ingredient_occurence > max_occurence:
							max_occurence = ingredient_occurence
							main_ingredient = ingredient
					return main_ingredient

				# question 7. recette sans un ingrédient donné
				def get_recipe_without(book, ingredient):
					filtered_book = {}
					for recipe, ingredients in book.items():
						if ingredient not in ingredients:
							filtered_book[recipe] = ingredients
					return filtered_book

				# question 8. recette sans plusieurs ingrédients
				def get_recipe_without_multiple(book, banned_ingredients):
					filtered_book = {}
					for recipe, ingredients in book.items():
						target_ingredients = list(set(banned_ingredients) & set(ingredients))
						# target_ingredients contient une liste des ingrédients se trouvant à la fois
						# dans banned_ingredients et dans ingredients
						# voir le paragraphe "pour aller plus loin à propos des objets de type set"
						if len(target_ingredients) == 0:
							filtered_book[recipe] = ingredients
					return filtered_book
			

Les ensembles (set)

En Python, un ensemble (set) est une collection non ordonnée d’éléments uniques. Contrairement aux listes, les ensembles ne peuvent pas contenir de doublons et n’ont pas d’ordre défini. Ils sont particulièrement utiles lorsque l’unicité des éléments est importante et que l’ordre n’a pas d’importance.

Création et utilisation des ensembles


		# Création d’un ensemble
		nombres = {1, 2, 3, 4, 5}
		# ou avec le constructeur set()
		couleurs = set(["rouge", "vert", "bleu"])

		# Tentative d’ajout d’un doublon
		nombres.add(3) # L’ensemble ne change pas car 3 existe déjà
		print(nombres) # {1, 2, 3, 4, 5}

		# Ajout d’un nouvel élément
		nombres.add(6)
		print(nombres) # {1, 2, 3, 4, 5, 6}

		# Suppression d’un élément
		nombres.remove(2)
		print(nombres) # {1, 3, 4, 5, 6}
	

Quand utiliser un ensemble plutôt qu’une liste ?

1. Pour éliminer les doublons : si vous avez une liste avec des éléments répétés et souhaitez les éliminer.


		liste_avec_doublons = [1, 2, 2, 3, 4, 4, 5]
		liste_sans_doublons = list(set(liste_avec_doublons))
		print(liste_sans_doublons) # [1, 2, 3, 4, 5]
	
2. Pour les opérations ensemblistes : les ensembles permettent d’effectuer des opérations mathématiques comme l’union, l’intersection et la différence.

	ensemble_A = {1, 2, 3, 4}
	ensemble_B = {3, 4, 5, 6}

	# Union (tous les éléments des deux ensembles)
	print(ensemble_A | ensemble_B) # {1, 2, 3, 4, 5, 6}

	# Intersection (éléments présents dans les deux ensembles)
	print(ensemble_A & ensemble_B) # {3, 4}

	# Différence (éléments présents dans A mais pas dans B)
	print(ensemble_A - ensemble_B) # {1, 2}
	

3. Pour vérifier l’appartenance : la recherche d’un élément dans un ensemble est plus rapide que dans une liste.


		# Vérification d’appartenance dans une liste vs un ensemble
		grande_liste = list(range(1000000))
		grand_ensemble = set(range(1000000))

		# La recherche dans un ensemble est beaucoup plus rapide
		# surtout pour de grandes collections
		500000 in grand_ensemble # Très rapide
		500000 in grande_liste # Plus lent
	

Utilisez un ensemble quand vous avez besoin de garantir l’unicité des éléments, d’effectuer des opérations ensemblistes, ou d’optimiser les recherches d’appartenance. Utilisez plutôt une liste quand l’ordre des éléments est important ou quand vous avez besoin d’accéder aux éléments par leur indice.

Utilisation de Set

Voici deux listes.


			fruits = ["pomme", "banane", "orange", "fraise", "cerise", 
			"poire", "abricot", "kiwi", "raisin", "mangue", 
			"ananas", "pêche", "citron", "framboise", "melon", 
			"pastèque", "myrtille", "mandarine", "prune", "figue", 
			"grenade", "litchi", "noix de coco", "groseille", "cassis"]

			food = ["farine", "oeuf", "jambon", "poireau", "pomme", 
			"riz", "poulet", "carotte", "oignon", "lait", 
			"beurre", "fromage", "sel", "poivre", "sucre", 
			"pain", "pâtes", "thon", "yaourt", "banane", 
			"orange", "chocolat", "huile", "miel", "noix de coco"]
		

Proposer une manière d’obtenir les listes suivantes :

  1. une liste avec tous les éléments de ces deux listes, sans doublon ;
  2. une liste avec tous les éléments communs à ces deux listes ;
  3. la liste food sans les éléments présents dans la liste fruits.