Tableaux indexés, les listes

Représentation des données: types construits

Plan

Présentation

Vous pouvez trouver un cours simplifié ici.

Les listes aussi appelées tableaux sont un élément indispensable en programmation. Comment faire pour travailler sur des valeurs que l'utilisateur va saisir si l'on ne sait pas à l'avance combien de valeurs il va saisir. On ne peut plus utiliser les variables et il risquerait d'y en avoir beaucoup! C'est là où peuvent intervenir les listes. En python les listes sont muables (on peut les modifier) et contiennent une série de données qui peuvent être de types différents.

A noter aussi que l'on n'a pas besoin de définir la taille de la liste à l'avance. La taille de la liste c'est le nombre d'éléments contenus dans la liste, ce que l'on appelle longueur de la liste. Contrairement aux dictionnaires, la liste est indexée, ce qui signifie que chaque élément est associé à un nombre appelé index.

Les index commencent à 0 et sont incrémentés de 1 à chaque nouvel élément. Sans intervention de notre part, l'ordre dans la liste est figé. Attention toutefois, contrairement à une clé (voire dictionnaires), les index ne sont pas définitivement attribués à une valeur. En effet, si vous effacez un élément d'une liste, tous les éléments qui sont placés après celui qui est supprimé verront leur index décrémenté. Vous comprendrez mieux plus loin avec des exemples et pourrez relire ces lignes.

Créer et ajouter des éléments dans une listes

Voici les commandes de base pour créer une liste vide, une liste contenant déjà des éléments, ajouter des éléments à une liste...
#Creer une liste vide
liste1=[]
#creer une liste initialisée avec des éléments
liste2=[3,"bonjour",True,(3,4,5),{'tel': '0606060606'}]
#créer avec des éléments identiques
liste1=["bon"]*2  #fera ["bon","bon"]
#ajouter un élément à une liste
liste1.append("1er élément")
#ajouter plusieurs éléments
liste2.extend([10,11,12])
#afficher une liste
print(liste1)
#afficher le 1er élément d'une liste
print(liste2[0])
#connaitre la longueur de la liste
longueur=len(liste2)
#afficher le dernier élément
print(liste2[len(liste2)-1])
print(liste2[-1])
#changer l'élément 1 par une autre valeur
liste1[1]="nouvelle valeur"
#index négatif...oui c'est possible
print(liste2[-1])
#va afficher le dernier élément, -2 l'avant dernier, etc...

Remarquez la notation de la méthode (oui j'ai dit méthode et non instruction ou commande) append et extend. On ne met pas comme d'habitude une instruction et entre parenthèses ses paramètres mais le nom de la liste puis un point et enfin le nom de la méthode append. Cela vient du fait qu'en Python les listes sont des objets et que les objets ont des méthodes qui leurs sont propres et que l'on appelle avec un point (du moins en Python et dans de nombreux langages mais pas en php...). Pour l'instant contentez-vous de mémoriser leur implémentation.

Boucles et listes

Il existe des manières très différentes de balayer tous les éléments d'une liste

La première consiste à lire tous les éléments en les appelant par leur index. On fera donc une boucle allant de 0 jusqu'à la longueur de la liste-1 et de lire les éléments en les appelants avec leur index: liste[i].

La deuxième méthode est de réaliser une itération sur l'ensemble de éléments de la liste. On utilise cette méthode lorsque l'on n'a pas besoin de connaitre la position de l'élément dans la liste.

Afin de ne pas s'embrouiller entre ces deux méthodes je conseille vivement de choisir des variables au nom très évocateur pour ne pas confondre l'index et l'élément. Pour cela je conseille de prendre la variable i pour l'index et de prendre la variable element pour l'élément.

Voici l'affichage de la liste1 avec ces deux méthodes.

# affichage avec boucle sur index
for i in range(len(liste2)):
	print(liste2[i])
# affichage avec boucle sur éléments:
for element in liste2:
	print(element)

Instructions supplémentaires

Toutes les commandes qui vont suivre nous simplifient la vie dans la manipulation des listes mais pourraient toutes être codées par vous avec seulement les éléments donnés précédemments. Nous ferons donc ces exercices! Premier élément le slice ":"

# éléments de l'index 1 à 2
print(liste2[1:3])
# éléments de l'index 1 à la fin de la liste
print(liste2[1:])
# "élément jusqu'à l'index 2
print(liste2[:3])
# remplacer plusieurs éléments à la fois
liste2[1:3]=[7,"coucou"]

Maintenant les commandes de suppression, insertion et copie de liste

# effacer un élément à un index donné avec pop et le récupérer en même temps
l=liste2.pop(0)
print(l)
# à noter,la méthode pop retourne et efface la valeur du
# dernier élément lorsque l'on ne donne pas d'index
print(liste2.pop()) # affiche le dernier élément de la liste.
# effacer un élément d'une valeur donnée avec remove
liste2.remove("bonjour")
#effacer l'élément en position 1
del liste2[1]
# inserer en position 1
liste2.insert(1,"inséré")
# trouver l'index d'un élément, attention,
# provoque une erreur si l'élément n'est pas dans la liste
liste2.index("inséré")
#pour vérifier qu'un élément est dans une liste:
2 in liste2
#donne un booléen True or False
# ranger la liste dans l'ordre croissant des éléments
#attention on ne peut pas taper l=liste2.sort()
#sort est une méthode de liste qui ne renvoie rien
#mais modifie directement la liste !
liste2.sort()
#inverser l'ordre d'un liste (je n'ai pas dit ranger dans l'ordre décroissant!)
liste2.reverse() # idem mais à l'envers
# copier une liste et avoir une copie indépendante
liste3=liste2.copy()
Attention si l'on fait liste3=liste2, alors liste3 et liste2 sont les mêmes objets et donc toute modification de liste2 modifie liste3 et réciproquement. La méthode copy réalise une shallow copy . Pour une copie plus indépendante (des listes dans des listes ne sont pas indépendantes avec copy) on utilisera deepcopy du module copy.

Les compréhensions de liste python

La compréhension de liste est une ligne de code permettant d'avoir moins de lignes de code pour la création d'une liste. La lecture de cette ligne de code est assez simple à comprendre même si elle peut dérouter au début.

Voici la syntaxe: [function(item) for item in list if condition(item)]

Voici de nombreux exemples, je pense qu'ils sont assez simples pour être compris et cela vous fera déjà un bon exercice de compréhension (le jeu de mot!)

chiffres=[x for x in range(10)]
pairs=[x for x in chiffres if x%2==0]
impairs=[x+1 for x in pairs]
plusDeCinq=[x for x in chiffres if x>5]
oppose=[-x for x in chiffres]
opposePairSeulement=[-x if x%2==0 else x for x in chiffres]
table= [ [i * j for i in range(10)] for j in range(10)]
print('\n'.join(' '.join(map(str,sl)) for sl in table)) #ouf...ce n'est pas de moi ça
#voici de quoi afficher la table plus simplement
for line in table:
	print(line)

J'ai pu constater que python est plus rapide avec cette méthode qu'avec une boucle. Probablement parce que la ligne est interprétée en une seule étape.

Listes et fonctions

Les listes sont des objets, de ce fait, lorsque l'on tape liste1=liste2, liste1 et liste2 sont en fait la même liste et seule une shallow copy ou deep copy (copy ou deepcopy) font une copie de la liste. Cela modifie aussi le comportement de la liste lorsque l'on envoie une liste dans une fonction. Comme on envoie l'adresse de la liste, toute modification de la liste dans la fonction, modifie la liste qui se trouve dans le programme principal. Voyez ci-dessous, deux exemples de fonctions, l'une avec des variables et l'autre avec des listes. Dans la fonction avec des listes, je n'ai pas besoin de return car, ma liste qui est passée en paramètre, sera aussi modifiée dans le programme principal, même s'il n'y a pas de return. Si l'on ne veut pas modifier la liste du programme principal, la première chose à faire dans la fonction est de créer une shadow ou deep copie de la liste et de renvoyer cette copie si l'on a besoin des modifications.

def liste_modif(liste,a,b):
    """ajoute deux éléments à une liste
     paramètres: une liste et deux variables
     """
    liste.append(a)
    liste.append(b)

def liste_modif2(liste,a,b):
    """renvoie une nouvelle liste
    avec la liste de départ et l'ajout de deux éléments
     paramètres: une liste et deux variables
     """
    l=liste.copy()
    l.append(a)
    l.append(b)
    return(l)

def variable_modif(a):
    """incrémente de 1
    paramètre: un float
    """
    a=a+1
    return(a)


########################################
###        pgm principal             ###
########################################

liste1=[3,7]
liste2=liste1
liste2.append(10)
print("liste1 ",liste1)
#on voit que comme liste1=liste2, la modif sur liste2
#s'est aussi répercutée sur liste1
liste_modif(liste1,20,30)
print("liste1",liste1)
#voyez que je n'ai pas mis liste1=liste_modif(liste1,20,30)
#normal, la fonction n'a pas de return!
#et pourtant je récupère bien ma liste modifiée
liste3=liste_modif2(liste1,40,50)
print("liste1",liste1)
print("liste3",liste3)
#voyez que j'ai du taper liste3=, pour utiliser le return
#et que liste1 n'est pas modifiée.
a=10
b=variable_modif(a)
print(a)
print(b)
#on voit que le comportement n'est pas le même
#avec les variables
#Avec une variable, ce qui se passe dans la fonction
#est indépendant du programme principal

Message d'erreur

Il y a de fortes chances que vous ayez un jour ou l'autre le message suivant: "index out of range". Cela signifie que vous utilisez un index qui dépasse la longueur de la liste. La méthode index renvoie ValueError si l'élément cherché n'est pas trouvé. Pour éviter cela on utilise en premier la méthode count qui donne le nombre d'occurence de l'élément cherché dans la liste ou 'is in'.

Exercices

  1. Créer un liste nommée liste avec les éléments 17,3,28,15,"dix",1. Puis supprimer "dix". Puis afficher la liste. Ajouter l'élément 13 à la liste. Ordonner puis afficher la liste. Afficher la liste à partir de 2ème élément. Afficher la sous liste du 1er au 3ème. Afficher l'avant dernier élément.

  2. Faites en sorte que l'utilisateur puisse remplir une liste qu'avec des nombres positifs et que lorsqu'il saisit 0, la saisie cesse. Calculer la somme (sans utiliser sum) des éléments puis la moyenne de la liste. Augmenter de 1 tous les nombres de la liste.

  3. En utilisant la commande split(' '), écrire un programme qui va mettre dans une liste tous les mots d'une phrase séparés par un espace. Afficher le nombre de mots de cette phrase. Par exemple, "Il fait beau".split() retourne ['il', 'fait', 'beau']

  4. a) Ecrire une fonction qui cherche tous les diviseurs d'un nombre n
    b) Ecrire une fonction qui inqique si deux nombres sont premiers entre eux (en utilisant le a).

  5. Soit un=3un-1-2un-2 avec u0 et u1 choisis par l'utilisateur. Stocker les 50 premières valeurs de u dans une liste.

  6. Ecrire une fonction ma_copie qui créer une shallow copie sans utiliser la fonction copy.

  7. Ecrire une fonction qui affiche une matrice. (une matrice est un tableau a deux dimensions que l'on crée avec une liste de liste. Par exemple m[[1,2],[10,20],[30,40]] est une matrice de dimension 2 sur 3. Pour afficher le 10 on fait m[1][0])

  8. Une matrice n X m contient n lignes et m colonnes. Une matrice carrée est du type n X n. Pour additionner deux matrices de même taille, on additionne les éléments qui sont au même emplacement ensemble. Voici comment créer une matrice 3x3: matrice=[[1,2,3],[4,5,6],[7,8,9]]. C'est une liste de liste. pour accéder au 7 il faut faire matrice[2][0]. Pour parcourir, il faut faire des boucles imbriquées.

  9. Pour multiplier deux matrices carrées, l'élément i,j du résultat s'obtient en multipliant la ligne i avec la ligne j membre à membre. Ecrire une fonction de multiplication de matrices carrées.

  10. Ecrire une fonction qui cherche si un élément est dans une liste sans utiliser 'in'.

  11. Ecrire une fonction qui insère un élément en ième position sans utiliser insert

  12. Ecrire une fonction qui supprime le ième élément sans utiliser del, ni pop.

  13. Série deux, on repart de facile

  14. Ecrire une fonction permute les éléments d'index i et j d'une liste.

  15. Ecrire une fonction qui renvoie un booléen pour indiquer qu'une liste est rangée dans l'ordre croissant.

  16. Afficher une liste à l’envers, sans créer de nouvelle liste.

  17. Modifier la liste par permutation circulaire (chaque élèment descend d'un index et l'élément 0 devient le dernier) sans créer de nouvelle liste.

  18. Ecrire une fonction qui retourne un booléen pour indiquer qu'une liste est symétrique (la même dans les deux sens de lecture).

  19. Supposons que nous stockons les dates dans une liste de longueur 3: jour,mois,année. Nous avons une liste qui contient des dates. Ecrire une fonction qui vérifie que les dates données sont correctes (On aura besoin de la fonction bissextile faite il y a un moment !)
    Correction Prof

    Correction Basile

    Correction Nathan

    Correction Guillem

  20. Listes par compréhension

  21. Créer en une seule ligne, par compréhension, une liste qui sera l'inverse d'une liste donnée.

  22. Créer en une seule ligne, par compréhension, une liste qui sera la permutation circulaire de 1 rang (dans le sens de votre choix) d'une liste donnée. (voir ex 16)

  23. Créer en une ligne, par compréhension, la liste des années bissextile de 1600 à 2010.

Android

De la programmation pour pc à la programmation pour téléphone.

A finir

Pas eu le temps de tout faire.....