VaultBy ENSAMIENParrainage
Notebook

TDP 4 : Liste, Set, Dictionnaires

correction.ipynb

  • Nom : CHOUBIK
  • Prénom : Houssam
  • Filière : CS2C - 1

Exercice 1: Supprimer les doublons d'une liste

  • Générer une liste L de 40 entiers entre 8 et 24
import random
# pour generer un nombre entier aleatoirement entre Vmin et Vmax
Vmin = 8 # Ex
Vmax = 24 # Ex
L = [random.randint(Vmin,Vmax) for _ in range(40)]
print(L)
[16, 11, 13, 12, 13, 18, 13, 17, 17, 21, 23, 22, 16, 21, 9, 16, 24, 13, 9, 22, 15, 16, 24, 13, 23, 14, 19, 10, 16, 24, 13, 23, 12, 9, 10, 10, 8, 14, 11, 17]
  • Ecrire une fonction qui affiche le nombre le plus fréquent
def nombre_plus_frequent(liste):
    if not liste:
        print("La liste est vide.")
        return

    frequences = {}
    for item in liste:
        frequences[item] = frequences.get(item, 0) + 1
    
    num_max = max(frequences, key=frequences.get)
    freq_max = frequences[num_max]
    
    print(f"Le nombre le plus frequent {num_max}, son occurence est {freq_max}.")

nombre_plus_frequent(L)
Le nombre le plus frequent 13, son occurence est 6.
  • Ecrire une fonction qui supprime tous les doublons de la liste L. Vous pouvez utiliser un espace auxiliaire.
def supprimer_doublons(liste):
    liste_sans_doublons = []
    for item in liste:
        if item not in liste_sans_doublons:
            liste_sans_doublons.append(item)
    return liste_sans_doublons

L_sans_doublons_1 = supprimer_doublons(L)
print(L_sans_doublons_1)
[16, 11, 13, 12, 18, 17, 21, 23, 22, 9, 24, 15, 14, 19, 10, 8]
  • Refaire la question en utilisant la notion de set.
def supprimer_doublons_set(liste):
    return list(set(liste))
    
L_sans_doublons_2 = supprimer_doublons_set(L)
print(sorted(L_sans_doublons_2))
[8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24]
  • Remarques & Conclusions ?

On remarque que : - La première méthode garde l'ordre des éléments, la méthode avec le set ne le garde pas. - La première méthode est en O(n²) : item not in liste_sans_doublons parcourt la liste à chaque tour. - La méthode avec le set est en O(n) en moyenne, donc beaucoup plus rapide sur de grandes listes.

Exercice 2 : set

  • creer un set qui contient 35 éléments générés aléatoirement ayant des valeurs entre 0 et 50
ensemble = set()
while len(ensemble) < 35:
    ensemble.add(random.randint(0, 50))

print(ensemble)
{0, 1, 2, 3, 4, 6, 8, 9, 10, 13, 15, 16, 17, 19, 21, 22, 23, 26, 28, 29, 30, 31, 32, 33, 34, 35, 38, 40, 41, 42, 43, 44, 45, 48, 50}
  • Afficher la longuer du set !
print(f"La longueur est: {len(ensemble)}")
La longueur est: 35

Intersection de deux sets : - Écrire une fonction qui prend deux sets et retourne leur intersection (éléments communs).

set_A = {random.randint(1, 20) for _ in range(15)}
set_B = {random.randint(1, 20) for _ in range(15)}
print(set_A)
print(set_B)

def intersection(s1, s2):
    resultat = set()
    for element in s1:
        if element in s2:
            resultat.add(element)
    return resultat

print(intersection(set_A, set_B))


print(f"Intersection : {set_A & set_B}")
{2, 4, 5, 6, 9, 13, 14, 17, 18, 20}
{1, 2, 3, 4, 6, 7, 10, 14, 17, 18, 20}
{2, 4, 6, 14, 17, 18, 20}
Intersection : {2, 4, 6, 14, 17, 18, 20}
  • Refaire la question en utilisant la méthode .intersection()
print(f"Intersection : {set_A.intersection(set_B)}")
Intersection : {2, 4, 6, 14, 17, 18, 20}

Analyse de mots uniques

  • Ecrire une fonction qui nettoie une chaine de caractère de tous les caractères non alphabetique : ponctuation, caractères spéciaux ...
    • Vous pouvez utiliser .isalpha()
def nettoyer_chaine(chaine):
    chaine_propre = "".join(c for c in chaine if c.isalpha() or c.isspace())
    return chaine_propre.lower()
  • Écrire une fonction qui prend deux phrases en entrée, puis retourne un ensemble (set) contenant les mots présents dans l’une ou l’autre phrase mais pas dans les deux (différence symétrique des ensembles de mots).
def mots_uniques(phrase1, phrase2):
    mots1 = set(nettoyer_chaine(phrase1).split())
    mots2 = set(nettoyer_chaine(phrase2).split())
    
    return mots1.symmetric_difference(mots2)

p1="salut tout le monde merci a @tous"
p2="salut tout univers merci heureux"


print(f"Phrase 1: '{p1}'")
print(f"Phrase 2: '{p2}'")
print(mots_uniques(p1, p2))
Phrase 1: 'salut tout le monde merci a @tous'
Phrase 2: 'salut tout univers merci heureux'
{'heureux', 'univers', 'a', 'monde', 'le', 'tous'}

Exercice 3: Fusion et Inversion de dictionnaires

soit le code ci-dessous pour génerer une chaine de caractère aléatoires de longueur Lg:

import random
import string

Lg = 30
# Génération d'un texte de Lg lettres (majuscules et minuscules)
ch = ''.join(random.choices(string.ascii_letters, k=Lg)).upper()
print(ch)
FPEEFURZCOJAGTAGEOBKXCEPVOQENY
  • Générer deux chaines de caractères majuscules ch1 et ch2 de longueurs Lg (ne contenant pas d'espaces)
ch1 = ''.join(random.choices(string.ascii_uppercase, k=Lg))
ch2 = ''.join(random.choices(string.ascii_uppercase, k=Lg))

print(f"Chaine 1: {ch1}")
print(f"Chaine 2: {ch2}")
Chaine 1: PVXWHKKKQDQJFZSUOQWWBHOAHZHZCJ
Chaine 2: XSAGYCVBPKMWWUCHBLOMQELCEXPCGQ
  • Écrire la fonction FrqLet qui prend en paramètre une chaine et retourne un dictionnaire des fréquences de chaque lettre de la chaine
def FrqLet(ch):
    # ecrire votre solution ici
    frequences = {}
    for lettre in ch:
        frequences[lettre] = frequences.get(lettre, 0) + 1
    return frequences
  • appliquer FrqLet() ) à ch1 et ch2
  • soit D1 et D2 les deux dictionnaires resulatnts
  • Écrire une fonction qui fusionne les deux dictionnaires dans un troisième D3, En cas de conflit, faire la somme des frequences.
D1 = FrqLet(ch1)
D2 = FrqLet(ch2)
print(D1)
print(D2)

def fusionner_somme(d1, d2):

    d3 = d1.copy()
    for cle, valeur in d2.items():
        d3[cle] = d3.get(cle, 0) + valeur
    return d3

D3 = fusionner_somme(D1, D2)
print(D3)
{'P': 1, 'V': 1, 'X': 1, 'W': 3, 'H': 4, 'K': 3, 'Q': 3, 'D': 1, 'J': 2, 'F': 1, 'Z': 3, 'S': 1, 'U': 1, 'O': 2, 'B': 1, 'A': 1, 'C': 1}
{'X': 2, 'S': 1, 'A': 1, 'G': 2, 'Y': 1, 'C': 4, 'V': 1, 'B': 2, 'P': 2, 'K': 1, 'M': 2, 'W': 2, 'U': 1, 'H': 1, 'L': 2, 'O': 1, 'Q': 2, 'E': 2}
{'P': 3, 'V': 2, 'X': 3, 'W': 5, 'H': 5, 'K': 4, 'Q': 5, 'D': 1, 'J': 2, 'F': 1, 'Z': 3, 'S': 2, 'U': 2, 'O': 3, 'B': 3, 'A': 2, 'C': 5, 'G': 2, 'Y': 1, 'M': 2, 'L': 2, 'E': 2}
  • Retrouver le résultat precedant en concatenant ch1 et ch2 dans une chaine ch3
ch3 = ch1 + ch2
D3_verif = FrqLet(ch3)
print(D3_verif)
print(D3 == D3_verif)
{'P': 3, 'V': 2, 'X': 3, 'W': 5, 'H': 5, 'K': 4, 'Q': 5, 'D': 1, 'J': 2, 'F': 1, 'Z': 3, 'S': 2, 'U': 2, 'O': 3, 'B': 3, 'A': 2, 'C': 5, 'G': 2, 'Y': 1, 'M': 2, 'L': 2, 'E': 2}
True
  • Écrire une fonction qui inverse les clés et les valeurs d'un dictionnaire (clé ↔ valeur).
    Si plusieurs clés ont la même valeur, stocker les clés dans une liste.
    Exemple : {'a': 1, 'b': 2, 'c': 1} → {1: ['a', 'c'], 2: ['b']}
def invDic(di):
    d_inverse = {}
    for cle, valeur in di.items():
        d_inverse.setdefault(valeur, []).append(cle)
    return d_inverse

d_exemple = {'a': 1, 'b': 2, 'c': 1, 'd': 3, 'e': 2}
d_inverse_exemple = invDic(d_exemple)
print(f"\norginale: {d_exemple}")
print(f"Inverse: {d_inverse_exemple}")
orginale: {'a': 1, 'b': 2, 'c': 1, 'd': 3, 'e': 2}
Inverse: {1: ['a', 'c'], 2: ['b', 'e'], 3: ['d']}

Exercice 4 : Dictionnaire indexé par tuple

import random
# pour generer un nombre entier aleatoirement entre Vmin et Vmax
random.randint( -10, 10)
-8
  • Générer aléatoirement une liste LP de 300 points dont les coordonnés (x,y) sont des entiers (relatifs) entre -15 et 15
import math

LP = [(random.randint(-15, 15), random.randint(-15, 15)) for _ in range(300)]

print(LP)
print(f"Nombre de points : {len(LP)}")
[(-13, -5), (-5, -11), (-1, -1), (-1, -1), (8, 9), (-8, -5), (4, -9), (-6, -14), (-9, -12), (2, 15), (-9, -4), (-9, 14), (-6, -15), (-7, -2), (-14, 5), (12, 7), (0, -3), (9, -7), (10, 5), (-5, -4), (-15, 12), (-15, 7), (12, 12), (-6, -1), (1, 13), (-6, 4), (-4, 5), (-7, 7), (4, 10), (3, -15), (8, 0), (-3, -9), (-8, -8), (-10, 14), (-10, -6), (1, 4), (-3, -14), (-7, 6), (-10, -5), (1, -7), (1, -7), (-9, 9), (2, -1), (-10, -3), (-14, -4), (2, 3), (-6, -6), (1, 8), (-11, 13), (1, -3), (8, -12), (-4, -1), (-13, -10), (8, -13), (3, 0), (13, 9), (6, -4), (-14, 12), (10, -10), (13, 15), (-1, 2), (0, 3), (-9, -3), (7, 11), (7, 9), (5, -4), (-4, -7), (-5, 15), (-5, -15), (-6, 7), (10, 3), (-11, 5), (-3, 8), (-8, 7), (14, 12), (-15, 7), (-9, -5), (-11, -15), (-7, 15), (-5, 1), (8, -3), (-4, 3), (8, 15), (-12, 8), (-10, -2), (9, -1), (10, -10), (-15, 5), (-10, 8), (-15, 14), (-6, -10), (-4, 0), (2, 1), (5, 4), (11, -6), (-4, 1), (-5, -11), (-11, 6), (-12, -14), (11, -12), (-11, 2), (2, 13), (15, -15), (6, 1), (12, 7), (10, 15), (14, 15), (2, 5), (10, 13), (-13, -7), (14, -6), (-4, 4), (0, -5), (11, 6), (0, -7), (-8, 2), (-13, -3), (-13, 11), (-15, 8), (-14, -1), (-12, 11), (5, 7), (-11, 7), (5, -4), (-10, 5), (5, 9), (7, 12), (1, -6), (-3, -11), (14, -11), (13, -1), (10, 12), (-9, 4), (8, 0), (5, 14), (14, -10), (14, -15), (11, 6), (9, -15), (-6, -9), (-2, -14), (14, -7), (-4, -4), (13, -14), (-11, 7), (3, -2), (7, 4), (5, 11), (-9, 12), (-4, -4), (-4, -8), (13, 8), (-9, -13), (-15, 14), (7, 14), (-12, 6), (-11, -1), (-13, 11), (-5, -15), (13, -7), (12, 2), (15, -12), (-1, -5), (15, 2), (5, 9), (2, -8), (10, -2), (-8, 0), (-5, 13), (-3, 11), (-1, -12), (7, 2), (-7, 3), (-3, 6), (-10, -2), (-6, 11), (15, -15), (14, 1), (-3, 10), (10, -12), (6, -2), (-7, 0), (-9, 8), (-3, 5), (6, 11), (15, -10), (-1, 5), (-4, -12), (1, -15), (10, -8), (-13, 10), (-14, 5), (-2, -9), (-5, -12), (-7, 11), (9, 3), (-9, -9), (1, 11), (10, -8), (-12, 4), (-15, 13), (-8, 15), (2, 4), (15, -9), (15, 14), (-10, -1), (-6, 13), (1, 10), (7, 1), (12, -1), (-11, 1), (15, -7), (3, -13), (-4, -12), (8, 4), (-15, -5), (-1, 4), (3, 15), (11, 6), (-10, 2), (-5, 10), (-8, -12), (-5, -4), (4, -14), (-11, 13), (-3, 0), (8, -4), (-15, -3), (6, 8), (0, 6), (-2, 10), (12, 0), (-5, -2), (-2, 11), (-5, -9), (-13, -13), (-2, -11), (1, -8), (-10, 4), (-13, -4), (13, -6), (-3, 2), (14, -15), (-6, -10), (9, 2), (8, -13), (-4, -12), (6, -3), (9, 8), (0, 13), (12, -3), (-7, -8), (-11, -7), (-11, -11), (-3, 4), (11, -9), (-7, -10), (15, -13), (10, 6), (1, -5), (13, 14), (-3, -6), (13, 11), (3, 11), (-4, 14), (-10, 5), (-6, -2), (2, -4), (0, 9), (6, -4), (13, 15), (-14, 2), (-8, -6), (-1, -2), (-1, -9), (-3, 5), (9, -2), (2, -3), (-12, 8), (10, -14), (-7, -7), (-11, 7), (-9, 0), (-13, -9), (-15, 14), (7, -12), (4, -3), (12, 8), (14, -9), (11, 6), (-14, 14), (-4, 5), (-4, 5), (-12, 6), (14, 13), (10, 8), (5, 5), (-12, -15), (-6, -3), (-4, 8)]
Nombre de points : 300

À partir de la liste de LP, créer un dictionnaire DP dont la clé est le tuple (x, y) et la valeur est la distance euclidienne à l’origine.
N.B. le dictionnaire DP ne doit pas contenir de doublons

DP = {
    point: math.sqrt(point[0]**2 + point[1]**2) 
    for point in set(LP)
}

print(f"Nombre de points : {len(DP)}")
Nombre de points : 262
  • écrire une fonction PtInf qui retourne tous les points de DP qui sont à une distance à P inférieure à d
    • Le dictionnaire D, la distannce d et le point P sont des paramètres de la fonction
def PtInf(D , d, P = (0,0)):
    points_proches = []
    px, py = P
    for point_courant in D.keys():
        cx, cy = point_courant
        distance = math.sqrt((cx - px)**2 + (cy - py)**2)
        if distance < d:
            points_proches.append(point_courant)
            
    return points_proches
    
points_proches_origine = PtInf(DP, 5)
print(f"\nPoints proche de l'orgine : {points_proches_origine}")

point_ref = (10, 10)
points_proches_de_P = PtInf(DP, 4, P=point_ref)
print(f"Points proche de P {point_ref}: {points_proches_de_P}")
Points proche de l'orgine : [(-4, 1), (-1, -1), (-1, -2), (2, 4), (2, -3), (-1, 2), (-4, -1), (-1, 4), (-4, 0), (0, -3), (3, -2), (-3, 0), (3, 0), (-3, 2), (2, 1), (1, 4), (2, 3), (1, -3), (2, -4), (2, -1), (0, 3)]
Points proche de P (10, 10): [(8, 9), (9, 8), (13, 8), (7, 12), (10, 8), (7, 9), (12, 8), (13, 9), (7, 11), (10, 12), (13, 11), (12, 12), (12, 7), (10, 13)]

    Type at least 2 letters. ↑ ↓ to move, Enter to open.