Algorithmique & Structures de données — Université de Genève
Objectifs d’apprentissage¶
À la fin de ce séminaire, vous serez capable de :
Essentiel (obligatoire)¶
Choisir entre
list,tuple,dictetsetpour des tâches courantesÉcrire des fonctions avec paramètres requis et paramètres par défaut
Expliquer ce qu’est une classe, ce que fait
__init__et à quoi se réfèreselfConstruire une petite classe
Studentavec des mises à jour de notes validées
Bonus (si le temps le permet)¶
Utiliser
*argset**kwargsen confianceAjouter des fonctionnalités supplémentaires à la classe, comme des rapports plus riches et des aides pour le meilleur sujet
Explorer des idées OOP additionnelles (exemples d’héritage/polymorphisme)
Partie 1 : Théorie¶
3.1 Listes¶
Une liste en Python est un conteneur qui stocke plusieurs valeurs.
numbers = [1, 2, 3, 4]Les listes sont :
Ordonnées → Conservent l’ordre d’insertion
Muables → Peuvent être modifiées
Flexibles → Peuvent contenir des types mixtes
Redimensionnables → Grandissent et rétrécissent dynamiquement
lst = [1, "hello", 3.14]Pensez à une liste comme à des cases indexées :
[ 10 | 20 | 30 | 40 ]
0 1 2 3Vous pouvez accéder directement aux positions, l’ajout en fin est rapide, l’insertion au milieu est plus lente (les éléments se décalent).
Opérations courantes :
lst[i] # access (fast)
lst.append(x) # add at end (fast)
lst.insert(i,x) # insert at position (slower)
lst.remove(x) # remove by value
lst.pop() # remove last
lst.pop(i) # remove at index
x in lst # search
lst.sort() # sort
lst[a:b] # slice# --- List creation ---
empty_list = []
numbers = [4, 2, 7, 1, 9, 3, 6]
mixed = [1, "hello", 3.14, True, None] # heterogeneous (avoid in practice)
from_range = range(1, 8)
print(f"numbers: {numbers}")
print(f"from_range: {from_range}")
# --- Indexing ---
print(f"\nnumbers[0] = {numbers[0]}" ) # first element
print(f"numbers[-1] = {numbers[-1]}") # last element (negative indexing)
print(f"numbers[-2] = {numbers[-2]}") # second-to-last
# --- Slicing: lst[start:stop:step] ---
print(f"\nnumbers[2:5] = {numbers[2:5]}" ) # indices 2,3,4
print(f"numbers[:3] = {numbers[:3]}" ) # first 3
print(f"numbers[4:] = {numbers[4:]}" ) # from index 4 to end
print(f"numbers[::2] = {numbers[::2]}" ) # every 2nd element
print(f"numbers[::-1] = {numbers[::-1]}" ) # reversed!
# --- Mutating methods ---
lst = [3, 1, 4, 1, 5, 9, 2, 6]
print(f"\nOriginal: {lst}")
lst.append(7) # add to end
print(f"After append(7): {lst}")
lst.insert(0, 0) # insert 0 at index 0
print(f"After insert(0, 0): {lst}")
removed = lst.pop() # removes and returns the last element
print(f"After pop(): {lst} (removed: {removed})")
lst.remove(1) # removes first occurrence of 1
print(f"After remove(1): {lst}")
lst.sort() # in-place sort (modifies lst)
print(f"After sort(): {lst}")
sorted_copy = sorted(numbers) # sorted() returns a NEW list
print(f"sorted(numbers): {sorted_copy} (original unchanged: {numbers})")
lst.reverse() # in-place reverse
print(f"After reverse(): {lst}")
# --- Useful functions ---
print(f"\nlen(numbers) = {len(numbers)}")
print(f"sum(numbers) = {sum(numbers)}")
print(f"min(numbers) = {min(numbers)}")
print(f"max(numbers) = {max(numbers)}")
print(f"9 in numbers: {9 in numbers}")
print(f"numbers.index(9): {numbers.index(9)}") # first index of value 9
print(f"numbers.count(9): {numbers.count(9)}") # how many times 9 appears3.2 Tuples — séquences immuables¶
Un tuple est comme une liste, mais immuable — une fois créé, ses éléments ne peuvent pas être modifiés. Utilisez des tuples lorsque vous voulez :
Garantir que les données ne seront pas modifiées accidentellement
Utiliser une collection comme clé de dictionnaire (les listes ne sont pas hashables, les tuples le sont)
Retourner plusieurs valeurs depuis une fonction
Représenter un enregistrement fixe (par ex.,
(lat, lon),(name, age))
Emballage et déballage¶
point = (3, 7) # packing
x, y = point # unpackingL’affectation multiple en Python utilise l’empaquetage/dépaquetage de tuple en interne :
a, b = b, a # swap without a temp variable!# --- Tuple creation ---
empty_tuple = () # or: tuple()
single = (42,) # ONE-element tuple needs a trailing comma!
point_2d = (3.0, 7.5)
rgb = (255, 128, 0) # orange colour
record = ("Alice", 21, "CS") # student record
print(f"point_2d: {point_2d}")
print(f"rgb: {rgb}")
print(f"record: {record}")
# Single element gotcha:
not_a_tuple = (42) # This is just the integer 42 in parentheses
is_a_tuple = (42,) # This is a tuple with one element
print(f"\n(42) → type: {type(not_a_tuple)}")
print(f"(42,) → type: {type(is_a_tuple)}")
# --- Indexing (same as lists) ---
print(f"\npoint_2d[0] = {point_2d[0]}")
print(f"point_2d[1] = {point_2d[1]}")
print(f"record[-1] = {record[-1]}") # last element
# --- Immutability ---
try:
point_2d[0] = 99 # TypeError!
except TypeError as e:
print(f"\nTypeError: {e}")
# --- Unpacking ---
x, y = point_2d
print(f"\nUnpacked point: x={x}, y={y}")
name, age, major = record
print(f"Unpacked record: name={name}, age={age}, major={major}")
# Extended unpacking with *
first, *rest = [1, 2, 3, 4, 5]
print(f"\nfirst={first}, rest={rest}")
*beginning, last = [1, 2, 3, 4, 5]
print(f"beginning={beginning}, last={last}")
# --- Pythonic swap ---
a, b = 10, 20
print(f"\nBefore swap: a={a}, b={b}")
a, b = b, a # tuple packing/unpacking under the hood
print(f"After swap: a={a}, b={b}")
# --- Functions returning multiple values (tuples) ---
def min_and_max(lst):
"""Return (minimum, maximum) of a list."""
return min(lst), max(lst) # returns a tuple
data = [4, 2, 9, 1, 7]
lo, hi = min_and_max(data) # unpack the returned tuple
print(f"\nData: {data}")
print(f"min={lo}, max={hi}")3.3 Dictionnaires — associations clé-valeur¶
Un dictionnaire (dict) associe des clés à des valeurs. Depuis Python 3.7 il est aussi ordonné selon l’ordre d’insertion.
Les clés doivent être hashables (immutables) : les chaînes, nombres, tuples conviennent ; les listes ne conviennent pas
Les valeurs peuvent être n’importe quoi — y compris d’autres dicts, listes, ou même des fonctions
La recherche par clé est en O(1) en moyenne (implémentation par table de hachage)
Cas d’utilisation courants¶
Compter des fréquences (
word → count)Mise en cache / mémoïsation (
input → result)Enregistrements structurés (
field → value)Listes d’adjacence pour un graphe (
node → [neighbours])
from collections import Counter
# --- Creating dicts ---
empty_dict = {}
student = {"name": "Alice", "age": 21, "major": "CS", "gpa": 3.8}
from_pairs = dict([("a", 1), ("b", 2), ("c", 3)]) # from list of tuples
using_dict = dict(x=10, y=20) # keyword arguments
print(f"student: {student}")
print(f"from_pairs: {from_pairs}")
# --- Access ---
print(f"\nstudent['name'] = {student['name']}")
# .get() is safer: returns None (or a default) if key doesn't exist
print(f"student.get('gpa') = {student.get('gpa')}")
print(f"student.get('phone') = {student.get('phone')}")
print(f"student.get('phone', 'N/A') = {student.get('phone', 'N/A')}")
# --- Modify / add / delete ---
student["age"] = 22 # modify existing key
student["email"] = "a@unige.ch" # add new key
del student["major"] # delete a key
print(f"\nModified student: {student}")
popped = student.pop("email") # remove and return a value
print(f"Popped email: {popped}")
# --- Iteration ---
print("\nIterating:")
for key in student.keys(): # or just: for key in student
print(f" key: {key}")
for value in student.values():
print(f" value: {value}")
for key, value in student.items(): # most common — unpack both
print(f" {key}: {value}")
# --- Nested dicts ---
course_db = {
"CS101": {"name": "Algorithmics", "students": 45, "instructor": "Prof. Smith"},
"CS201": {"name": "Databases", "students": 38, "instructor": "Prof. Jones"},
}
print(f"\nCS101 instructor: {course_db['CS101']['instructor']}")
# --- dict comprehension ---
word_lengths = {word: len(word) for word in ["hello", "world", "python"]}
print(f"Word lengths: {word_lengths}")
# --- Frequency counter (important pattern!) ---
sentence = "the quick brown fox jumps over the lazy dog"
word_freq = {}
for word in sentence.split():
word_freq[word] = word_freq.get(word, 0) + 1
print(f"\nWord frequencies: {word_freq}")
# Tip: Python's collections.Counter does this automatically:
counter = Counter(sentence.split())
print(f"Most common 3: {counter.most_common(3)}")3.4 Sets — collections d’éléments uniques¶
Un set est une collection non ordonnée d’éléments uniques. Il est implémenté comme une table de hachage, donc :
O(1) test de membership moyen (
x in s)O(1) ajout/suppression moyen
Pas d’éléments dupliqués — ajouter un élément existant n’a aucun effet
Pas d’indexation — les sets sont non ordonnés
Opérations sur les sets (mathématiques)¶
| Operation | Syntax | Symbol |
|---|---|---|
| Union | `a | bora.union(b)` |
| Intersection | a & b or a.intersection(b) | A ∩ B |
| Difference | a - b or a.difference(b) | A \ B |
| Symmetric diff | a ^ b or a.symmetric_difference(b) | A △ B |
| Subset | a <= b or a.issubset(b) | A ⊆ B |
# --- Creating sets ---
from_list = set([1, 2, 2, 3, 3, 3]) # duplicates removed!
print(f"from_list: {from_list} (duplicates removed)")
# --- Uniqueness ---
words = ["apple", "banana", "apple", "cherry", "banana", "date"]
unique_words = set(words)
print(f"\nOriginal list: {words}")
print(f"Unique set: {unique_words}")
# --- Add / remove ---
s = {1, 2, 3}
s.add(4) # add one element
s.add(2) # adding an existing element is a no-op
s.discard(10) # discard: no error if element not present
print(f"\nAfter add(4) and add(2): {s}")
# --- Set operations ---
a = {1, 2, 3, 4, 5}
b = {4, 5, 6, 7, 8}
print(f"\na = {a}")
print(f"b = {b}")
print(f"a | b (union): {a | b}")
print(f"a & b (intersection): {a & b}")
print(f"a - b (difference A\\B): {a - b}")
print(f"b - a (difference B\\A): {b - a}")
print(f"a ^ b (symmetric diff): {a ^ b}")
# --- Subset / superset ---
small = {2, 3}
large = {1, 2, 3, 4}
print(f"\n{small} is subset of {large}: {small <= large}")
print(f"{large} is superset of {small}: {large >= small}")
# --- Membership test: O(1) vs list O(n) ---
import timeit
big_list = list(range(100_000))
big_set = set(big_list)
list_time = timeit.timeit("99_999 in big_list", globals=globals(), number=10_000)
set_time = timeit.timeit("99_999 in big_set", globals=globals(), number=10_000)
print(f"\nMembership test (100k elements, 10k repetitions):")
print(f" list: {list_time:.4f}s")
print(f" set: {set_time:.6f}s")
print(f" Speedup: {list_time / set_time:.0f}x")3.5 Fonctions¶
Une fonction est un bloc de code réutilisable qui :
Prend zéro paramètre ou plus (paramètres) (entrées)
Exécute une logique
Optionnellement retourne une valeur (sans
return, une fonction retourneNone)
D’abord l’essentiel : les deux types de paramètres dont vous avez besoin aujourd’hui¶
def greet(name, greeting="Hello"):
return f"{greeting}, {name}!"| Type | Syntaxe | Description |
|---|---|---|
| Positionnel | def f(a, b) | Obligatoire, passé par position |
| Par défaut | def f(a, b=10) | Optionnel, possède une valeur de repli |
Bonus (si le temps le permet)¶
| Type | Syntaxe | Description |
|---|---|---|
*args | def f(*args) | Récupère les arguments positionnels supplémentaires sous forme de tuple |
**kwargs | def f(**kwargs) | Récupère les arguments nommés supplémentaires sous forme de dict |
| Keyword-only | def f(a, *, kw) | Doit être passé par nom (après *) |
Docstrings¶
Utilisez des docstrings dans les notebooks et les devoirs afin que les autres comprennent rapidement votre fonction :
def my_function(x):
"""One-line summary.
Parameters
----------
x : int
Description of x.
Returns
-------
int
Description of return value.
"""# --- CORE: positional + default parameters ---
def greet(name, greeting="Hello"):
"""Return a greeting string."""
return f"{greeting}, {name}!"
print(greet("Alice")) # uses default greeting
print(greet("Bob", "Good morning")) # overrides default
print(greet(greeting="Hi", name="Carol")) # keyword arguments
# --- CORE: return values + type hints ---
def add(a: int, b: int) -> int:
"""Add two integers and return the result."""
return a + b
print(f"add(3, 4) = {add(3, 4)}")
# --- BONUS: *args and **kwargs (optional today) ---
def my_sum(*args):
"""Sum any number of arguments."""
total = 0
for num in args:
total += num
return total
def print_info(**kwargs):
"""Print key-value pairs from keyword arguments."""
for key, value in kwargs.items():
print(f" {key}: {value}")
print(f"my_sum(1, 2, 3) = {my_sum(1, 2, 3)}")
print("Student info:")
print_info(name="Alice", age=21, gpa=3.8)
# Optional one-liner example used often in sorting
students = [("Alice", 3.8), ("Bob", 3.5), ("Carol", 3.9)]
students.sort(key=lambda s: s[1], reverse=True)
print(f"Sorted by GPA: {students}")3.6 Classes et programmation orientée objet¶
Une classe est un modèle pour créer des objets. Un objet (ou instance) est une réalisation concrète de ce modèle.
Constructeur et self (essentiel)¶
Quand vous écrivez student = Student("Alice", "S123"), Python fait deux étapes :
Crée un nouvel objet
StudentvideAppelle
Student.__init__(self, "Alice", "S123")pour initialiser ses données
À l’intérieur des méthodes, self signifie « cet objet courant ».
self.nameest lenamede cette instance spécifiqueUn autre objet possède son propre
self.nameséparé
Variable de classe vs attributs d’instance¶
Variable de classe : partagée par tous les objets (définie directement dans la classe)
Attribut d’instance : appartient à un seul objet (généralement défini dans
__init__)
class Student:
school = "UNIGE" # class variable (shared)
def __init__(self, name):
self.name = name # instance attribute (per object)
def label(self):
return f"{self.name} @ {self.__class__.school}"Concepts OOP essentiels¶
| Concept | Signification |
|---|---|
| Encapsulation | Regrouper données (attributs) et comportement (méthodes) |
| Abstraction | Cacher les détails d’implémentation ; exposer seulement une interface claire |
| Héritage | Une classe hérite d’attributs/méthodes d’une classe parente |
| Polymorphisme | Même nom de méthode/interface, comportement différent selon la classe (ex. dog.speak() vs cat.speak()) |
# --- A complete class example: BankAccount ---
class BankAccount:
"""A simple bank account with deposit, withdraw, and balance query."""
bank_name = "University Bank" # class variable (shared by all instances)
MIN_BALANCE = 0.0 # class-level constant
def __init__(self, owner: str, initial_balance: float = 0.0):
"""Constructor: initialise a newly created account object."""
if initial_balance < self.MIN_BALANCE:
raise ValueError("Initial balance cannot be negative")
self.owner = owner # instance attribute (specific object)
self._balance = initial_balance
self._transactions = []
def deposit(self, amount: float) -> None:
if amount <= 0:
raise ValueError("Deposit amount must be positive")
self._balance += amount
self._transactions.append(("deposit", amount))
def withdraw(self, amount: float) -> None:
if amount <= 0:
raise ValueError("Withdrawal amount must be positive")
if amount > self._balance:
raise ValueError(f"Insufficient funds (balance: {self._balance:.2f})")
self._balance -= amount
self._transactions.append(("withdrawal", -amount))
@property
def balance(self) -> float:
return self._balance
def get_history(self) -> list:
return list(self._transactions)
def label(self) -> str:
# Access class variable from inside the class
return f"{self.owner} @ {self.__class__.bank_name}"
def __str__(self) -> str:
return f"[{self.bank_name}] {self.owner}'s account — Balance: CHF {self._balance:,.2f}"
# --- Using the class ---
alice_account = BankAccount("Alice", initial_balance=1000.0)
bob_account = BankAccount("Bob", initial_balance=500.0)
print(alice_account)
print(bob_account)
print()
# Class variable access: via class and via objects
print(f"Bank name from class: {BankAccount.bank_name}")
print(f"Bank name via alice: {alice_account.bank_name}")
print(f"Label via method: {alice_account.label()}")
print()
alice_account.deposit(500.0)
alice_account.withdraw(200.0)
print(f"Balance after transactions: CHF {alice_account.balance:,.2f}")
print("Transaction history:")
for txn_type, amount in alice_account.get_history():
sign = "+" if amount > 0 else ""
print(f" {txn_type:<12}: {sign}CHF {amount:,.2f}")
print()
try:
alice_account.withdraw(10_000)
except ValueError as e:
print(f"Caught ValueError: {e}")Partie 2 : Exercices¶
Travaillez dans cet ordre :
Essentiel d’abord (obligatoire)
Bonus seulement après que l’essentiel fonctionne
Pour chaque exercice, exécutez les vérifications rapides fournies dans la cellule de code.
Exercice 1 (Essentiel) : Échauffement avec les compréhensions¶
En utilisant les compréhensions (introduites au Séminaire 2), résolvez chaque tâche :
Étant donné
numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3], produisez une liste triée de valeurs uniques.
Indice : utilisezset(...)puissorted(...).Étant donné
words = ["hi", "hello", "hey", "algorithmics", "data", "structures", "AI"], produisez un dictionnaire associant chaque mot à sa longueur, mais uniquement pour les mots de plus de 2 caractères.Étant donné
sentence = "the quick brown fox jumps over the lazy fox", produisez un ensemble de mots qui apparaissent plus d’une fois.
Bonus : réécrivez la tâche 3 sans appeler .count() dans la compréhension (utilisez d’abord un dict de fréquences).
# Exercise 1 — Comprehension warm-up
numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3]
words = ["hi", "hello", "hey", "algorithmics", "data", "structures", "AI"]
sentence = "the quick brown fox jumps over the lazy fox"
# TODO 1
sorted_unique = None
# TODO 2
word_lengths = None
# TODO 3
repeated_words = None
print("sorted_unique:", sorted_unique)
print("word_lengths:", word_lengths)
print("repeated_words:", repeated_words)
# Quick checks (uncomment after solving)
# assert sorted_unique == [1, 2, 3, 4, 5, 6, 9]
# assert word_lengths["hello"] == 5 and "hi" not in word_lengths
# assert repeated_words == {"the", "fox"}Exercice 2 (Essentiel) : Compteur de fréquence des caractères¶
Écrivez une fonction char_frequency(text) qui retourne un dictionnaire associant chaque caractère au nombre de fois où il apparaît dans text.
Ignorer la casse (traiter
'A'et'a'comme équivalents)Ignorer les espaces
Ensuite créez sorted_items, une liste de paires (char, count) triées par fréquence (les plus fréquents d’abord).
Bonus : en cas d’égalité de fréquence, triez alphabétiquement par caractère.
# Exercise 2 — Character frequency counter
def char_frequency(text):
# TODO: implement
# Step 1: normalise case with text.lower()
# Step 2: skip spaces
# Step 3: count with a dict and .get(char, 0) + 1
pass
sample = "Data Structures"
freq = char_frequency(sample)
# TODO: create sorted_items as list of (char, count), most common first
sorted_items = None
print("freq:", freq)
print("sorted_items:", sorted_items)
# Quick checks (uncomment after solving)
# assert freq["t"] == 3
# assert " " not in freq
# assert sorted_items[0][1] >= sorted_items[-1][1]
Exercice 3 (Essentiel) : Supprimer les doublons sans set()¶
Écrivez une fonction remove_duplicates(lst) qui retourne une nouvelle liste sans doublons, en préservant l’ordre original, sans utiliser set().
Indice : utilisez une liste seen ou un dict des valeurs vues.
Bonus : conservez l’ordre mais accélérez le test d’appartenance en combinant une liste (pour l’ordre) avec un set (pour la recherche des éléments vus).
# Exercise 3 — Remove duplicates without set()
def remove_duplicates(lst):
# TODO: implement
# Keep first appearance only, preserve order
pass
data = [3, 1, 3, 2, 1, 4, 2, 5]
result = remove_duplicates(data)
print("result:", result)
# Quick checks (uncomment after solving)
# assert result == [3, 1, 2, 4, 5]
# assert remove_duplicates([]) == []
Exercice 4 (Essentiel + Bonus) : Fusionner deux dictionnaires¶
Écrivez une fonction merge_dicts(d1, d2) qui fusionne deux dictionnaires. Si une clé existe dans les deux, la valeur de d2 doit prévaloir.
Essentiel : implémentez avec une boucle, puis avec
.update()Bonus : implémentez avec le déballage
**(et éventuellement|sur Python 3.9+)
# Exercise 4 — Merge two dictionaries
def merge_dicts_loop(d1, d2):
# TODO: core implementation with loops
pass
def merge_dicts_update(d1, d2):
# TODO: core implementation with .update()
pass
# BONUS
# def merge_dicts_unpack(d1, d2):
# return {**d1, **d2}
a = {"x": 1, "y": 2}
b = {"y": 99, "z": 3}
print("loop: ", merge_dicts_loop(a, b))
print("update:", merge_dicts_update(a, b))
# Quick checks (uncomment after solving)
# assert merge_dicts_loop(a, b) == {"x": 1, "y": 99, "z": 3}
# assert merge_dicts_update(a, b) == {"x": 1, "y": 99, "z": 3}
Exercice 5 (Essentiel + Bonus) : Classe Student¶
Étape A (préparation) : De fonction à méthode de classe¶
Avant d’écrire la classe complète, écrivez une fonction simple :
is_passing_average(grades_dict, threshold=50)
Celle-ci doit retourner True si la moyenne des notes est au moins égale à threshold.
Étape B (Essentiel) : Construire la classe¶
Implémentez une classe Student avec :
Attributs :
name(str),student_id(str),grades(dict mappant matière → note 0–100)Méthode
average_grade()→ floatMéthode
is_passing(threshold=50)→ boolMéthode
add_grade(subject, score)avec validation (0–100)Méthode
__str__pour un résumé lisible sur une seule ligne
Étape C (Bonus) : Étendre la classe¶
Si l’essentiel est fait, ajoutez :
best_subject()→ tuple(subject, score)report()sortie multi-lignes formatée__repr__pour le débogage
# Exercise 5 — Student class
# Step A (bridge): function first
def is_passing_average(grades_dict, threshold=50):
# TODO: implement
pass
# Step B (core): class
class Student:
def __init__(self, name, student_id):
self.name = name
self.student_id = student_id
self.grades = {}
def add_grade(self, subject, score):
# TODO: validate 0..100 and store
pass
def average_grade(self):
# TODO: average of grades dict values
pass
def is_passing(self, threshold=50):
# TODO: use average_grade()
pass
def __str__(self):
# TODO: return readable one-line summary
pass
# BONUS
# def best_subject(self):
# pass
#
# def report(self):
# pass
#
# def __repr__(self):
# pass
s = Student("Alice", "S123")
s.add_grade("Math", 80)
s.add_grade("Algorithms", 70)
print(s)
print("Average:", s.average_grade())
print("Passing:", s.is_passing())
# Quick checks (uncomment after solving)
# assert is_passing_average({"Math": 80, "Algo": 40}, threshold=60) is True
# assert round(s.average_grade(), 2) == 75.0
# assert s.is_passing(76) is False
Récapitulatif¶
Compétences essentielles de ce séminaire¶
| Sujet | Point clé |
|---|---|
| Structures de données | Choisir list, tuple, dict, set selon la tâche |
| Fonctions | Maîtriser d’abord paramètres positionnels + par défaut |
| Classes | __init__ est le constructeur ; self est l’objet courant |
| Conception de classe | Les variables de classe sont partagées ; les attributs d’instance sont par objet |
Récapitulatif de complexité (aperçu informel)¶
| Opération | list | dict | set |
|---|---|---|---|
| Accès par clé/index | O(1) | O(1) | — |
| Recherche | O(n) | O(1) average | O(1) average |
| Insertion | O(1) end, O(n) middle | O(1) average | O(1) average |
| Suppression | O(1) end, O(n) middle | O(1) average | O(1) average |
Si l’essentiel est clair, utilisez les tâches bonus pour approfondir votre pratique.
Séminaire suivant : Atelier de transfert avec lancement du projet.
Université de Genève — Algorithmique & Structures de données