Théorie des ensembles

Rédiger du code Python efficace

Logan Thomas

Scientific Software Technical Trainer, Enthought

Théorie des ensembles

  • Branche des mathématiques appliquée aux collections d'objets
    • p. ex., des sets
  • Python offre un type set intégré avec des méthodes :
    • intersection(): éléments présents dans les deux ensembles
    • difference(): éléments d'un ensemble mais pas de l'autre
    • symmetric_difference(): éléments présents dans un seul des deux ensembles
    • union(): éléments présents dans l'un ou l'autre ensemble
  • Test d'appartenance rapide
    • Vérifier si une valeur est dans une séquence ou non
    • Avec l'opérateur in
Rédiger du code Python efficace

Comparer des objets avec des boucles

list_a = ['Bulbasaur', 'Charmander', 'Squirtle']
list_b = ['Caterpie', 'Pidgey', 'Squirtle']

alt="Les Pokémon nommés Bulbasaur, Charmander et Squirtle dans une boîte intitulée List A, et les Pokémon Caterpie, Pidgey et Squirtle dans une autre boîte intitulée List B"

Rédiger du code Python efficace

Comparer des objets avec des boucles

list_a = ['Bulbasaur', 'Charmander', 'Squirtle']
list_b = ['Caterpie', 'Pidgey', 'Squirtle'] 

alt="Les Pokémon nommés Bulbasaur, Charmander et Squirtle dans une boîte intitulée List A, et les Pokémon Caterpie, Pidgey et Squirtle dans une boîte intitulée List B; Squirtle est encerclé dans les deux boîtes"

Rédiger du code Python efficace
list_a = ['Bulbasaur', 'Charmander', 'Squirtle']
list_b = ['Caterpie', 'Pidgey', 'Squirtle'] 
in_common = []

for pokemon_a in list_a:
    for pokemon_b in list_b:
        if pokemon_a == pokemon_b:
            in_common.append(pokemon_a)

print(in_common)
['Squirtle']
Rédiger du code Python efficace
list_a = ['Bulbasaur', 'Charmander', 'Squirtle']
list_b = ['Caterpie', 'Pidgey', 'Squirtle'] 
set_a = set(list_a)
print(set_a)
{'Bulbasaur', 'Charmander', 'Squirtle'}
set_b = set(list_b)
print(set_b)
{'Caterpie', 'Pidgey', 'Squirtle'}
set_a.intersection(set_b)
{'Squirtle'}
Rédiger du code Python efficace

Efficacité gagnée avec la théorie des ensembles

%%timeit
in_common = []

for pokemon_a in list_a:
    for pokemon_b in list_b:
        if pokemon_a == pokemon_b:
            in_common.append(pokemon_a)
601 ns ± 17.1 ns par boucle (moyenne ± éc.-type de 7 exécutions, 1000000 boucles chacune)
%timeit in_common = set_a.intersection(set_b)
137 ns ± 3.01 ns par boucle (moyenne ± éc.-type de 7 exécutions, 10000000 boucles chacune)
Rédiger du code Python efficace

Méthode des ensembles : difference

set_a = {'Bulbasaur', 'Charmander', 'Squirtle'}
set_b = {'Caterpie', 'Pidgey', 'Squirtle'}
set_a.difference(set_b)
{'Bulbasaur', 'Charmander'}

alt="Les Pokémon nommés Bulbasaur, Charmander et Squirtle dans une boîte intitulée Set A, et les Pokémon Caterpie, Pidgey et Squirtle dans une boîte distincte intitulée Set B; Bulbasaur et Charmander sont encerclés dans la boîte Set A"

Rédiger du code Python efficace

Méthode des ensembles : difference

set_a = {'Bulbasaur', 'Charmander', 'Squirtle'}
set_b = {'Caterpie', 'Pidgey', 'Squirtle'}
set_b.difference(set_a)
{'Caterpie', 'Pidgey'}

alt="Les Pokémon nommés Bulbasaur, Charmander et Squirtle dans une boîte intitulée Set A, et les Pokémon Caterpie, Pidgey et Squirtle dans une boîte distincte intitulée Set B; Caterpie et Pidgey sont encerclés dans la boîte Set B"

Rédiger du code Python efficace

Méthode des ensembles : symmetric_difference

set_a = {'Bulbasaur', 'Charmander', 'Squirtle'}
set_b = {'Caterpie', 'Pidgey', 'Squirtle'}
set_a.symmetric_difference(set_b)
{'Bulbasaur', 'Caterpie', 'Charmander', 'Pidgey'}

alt="Les Pokémon nommés Bulbasaur, Charmander et Squirtle dans une boîte intitulée Set A, et les Pokémon Caterpie, Pidgey et Squirtle dans une boîte intitulée Set B; Bulbasaur, Charmander, Caterpie et Pidgey sont encerclés"

Rédiger du code Python efficace

Méthode des ensembles : union

set_a = {'Bulbasaur', 'Charmander', 'Squirtle'}
set_b = {'Caterpie', 'Pidgey', 'Squirtle'}
set_a.union(set_b)
{'Bulbasaur', 'Caterpie', 'Charmander', 'Pidgey', 'Squirtle'}

alt="Les Pokémon nommés Bulbasaur, Charmander et Squirtle dans une boîte intitulée Set A, et les Pokémon Caterpie, Pidgey et Squirtle dans une boîte intitulée Set B; Tous les Pokémon sont encerclés et Squirtle n'est encerclé qu'une seule fois"

Rédiger du code Python efficace

Test d'appartenance avec des ensembles

# Les mêmes 720 Pokémon au total dans chaque structure de données
names_list  = ['Abomasnow', 'Abra', 'Absol', ...]
names_tuple = ('Abomasnow', 'Abra', 'Absol', ...)
names_set   = {'Abomasnow', 'Abra', 'Absol', ...}

alt="Les Pokémon nommés Abomasnow, Abra et Absol dans trois boîtes distinctes intitulées List, Tuple et Set respectivement"

Rédiger du code Python efficace

Test d'appartenance avec des ensembles

# Les mêmes 720 Pokémon au total dans chaque structure de données
names_list  = ['Abomasnow', 'Abra', 'Absol', ...]
names_tuple = ('Abomasnow', 'Abra', 'Absol', ...)
names_set   = {'Abomasnow', 'Abra', 'Absol', ...}

alt="Les Pokémon nommés Abomasnow, Abra et Absol dans trois boîtes distinctes intitulées List, Tuple et Set; le Pokémon Zubat avec une ligne vers chaque boîte représentant un test d'appartenance pour chacune"

Rédiger du code Python efficace
names_list  = ['Abomasnow', 'Abra', 'Absol', ...]
names_tuple = ('Abomasnow', 'Abra', 'Absol', ...)
names_set   = {'Abomasnow', 'Abra', 'Absol', ...}
%timeit 'Zubat' in names_list
7.63 µs ± 211 ns par boucle (moyenne ± éc.-type de 7 exécutions, 100000 boucles chacune)
%timeit 'Zubat' in names_tuple
7.6 µs ± 394 ns par boucle (moyenne ± éc.-type de 7 exécutions, 100000 boucles chacune)
%timeit 'Zubat' in names_set
37.5 ns ± 1.37 ns par boucle (moyenne ± éc.-type de 7 exécutions, 10000000 boucles chacune)
Rédiger du code Python efficace

Valeurs uniques avec des ensembles

# 720 types primaires de Pokémon correspondant à chaque Pokémon
primary_types = ['Grass', 'Psychic', 'Dark', 'Bug', ...]
unique_types = []

for prim_type in primary_types:
    if prim_type not in unique_types:
        unique_types.append(prim_type)

print(unique_types)
['Grass', 'Psychic', 'Dark', 'Bug', 'Steel', 'Rock', 'Normal',
 'Water', 'Dragon', 'Electric', 'Poison', 'Fire', 'Fairy', 'Ice',
 'Ground', 'Ghost', 'Fighting', 'Flying']
Rédiger du code Python efficace

Valeurs uniques avec des ensembles

# 720 types primaires de Pokémon correspondant à chaque Pokémon
primary_types = ['Grass', 'Psychic', 'Dark', 'Bug', ...]
unique_types_set = set(primary_types)
print(unique_types_set)
{'Grass', 'Psychic', 'Dark', 'Bug', 'Steel', 'Rock', 'Normal',
 'Water', 'Dragon', 'Electric', 'Poison', 'Fire', 'Fairy', 'Ice',
 'Ground', 'Ghost', 'Fighting', 'Flying'}
Rédiger du code Python efficace

Passons à la pratique avec la théorie des ensembles!

Rédiger du code Python efficace

Preparing Video For Download...