IiP 5 : Listes

Initiation interactive à Python 5 : Listes #

Aller vers Initiation interactive à Python 4 : les boucles
Cette page n’est pas tout à fait terminée 8-)

Les listes sont les conteneurs Python les plus utilisés. Elle permettent de stocker de manière séquentielle des références vers d’autres objets : des nombres, des chaînes de caractères etc…

On peut ensuite accéder à un objet de la liste en donnant son numéro d’ordre (en faisant attention car la numérotation commence à 0).

Voici quelques exemples de manipulations de listes :

l = [2, 3, 5, 7, 11, 13]
print("Le plus petit nombre premier est : ", l[0])
print("Le sixième nombre premier est : ", l[5])
l.append(17)
print("Le septième est :", l[6]

Les listes sont des objets mutables ce qui signifie qu’on peut modifier les valeurs qu’elles contiennent.

On peut modifier le premier élément de la liste (par exemple) ainsi :

l[0] = 42

Il y a un certain nombre d’opérations disponibles sur les listes :

l = [1, 2, 5, 3, 1, 13, 8]
n = len(l) # nombre d'éléments de la liste
print("La liste",l,"contient",n,"éléments")
l.sort() # trie la liste 
print(l)

Voici quelques autres opérations réalisables avec des listes :

Méthode Type retour Description


list() list Renvoie une liste vide [item[,item]+] list Liste contenant les items donnés entre crochets del x[i] Efface l’objet en position i de x x[i]=e Affecte l’item e à la position i de x. L’item i doit déjà exister (la liste n’ets pas étirée). x+=y Modifie la liste x en lui ajoutant les éléments de y x*=i Modifie la liste x pour qu’elle contienne i copies concaténée de la liste originale. x.append(e) None Modifie x en lui ajoutant e comme dernire élément. x.count(e) int Retourne le nombre d’apparitions de e dans x. Les apparitions sont détectées en utilisant ==. x.extend(iter) None Modifie x en lui ajoutant les éléments de l’itérable iter. x.index(e,[i,[j]]) int Retourne l’indice du premier élément de x égale à e (au sens de ==), situé entre les indices i et j-1. L-ve l’exception ValueError si un tel élément n’existe pas. x.insert(i, e) None Modifie x en insérant e de tel sorte qu’il se trouve à l’indice i. x.pop([index]) item Supprime (modifie donc x) et renvoie l’élément en position index. Si index n’est pas précisé, il est pris par défaut égal à len(x)-1. x.remove(e) None Modifie x en supprimant la première occurence de e. Lève l’exception ValueError si e n’est pas trouvé. x.reverse() None Modifie x en renversant l’ordre de ses éléments. x.sort() None Modifie x pour qu’il soit trié en utilisant la méthode de comparaison __cmp__ de ses éléments. La méthode accepte deux paramètres optionels : key et reverse. Si reverse vaut True, le tri est fait à l’envers (décroissant). Le paramètre key est une fonction qui prend en paramètre un élément et renvoie la valeur qui sera utilisée réellement pour le tri.

Comme d’autres conteneurs Pythons, les listes font partie de la famille des séquences. Toutes les types séquence (les listes, mais aussi les tuples, les chaînes de caractères…) disposent des opérations suivantes:

Méthode Type retour Description


list(sequence) list Renvoie une liste contenant les objets de sequence x==y bool Retourne True si x et y contiennent les même objets (au sens de == pour chaque paire d’objets) x>=y bool Vrai si x est avant y dans l’ordre lexicographique ou si x==y. Faux sinon. x<=y bool Vrai si x est après y dans l’ordre lexicographique ou si x==y. Faux sinon. x>y bool Vrai si x est avant y dans l’ordre lexicographique. Faux sinon x<y bool Vrai si x est après y dans l’ordre lexicographique. Faux sinon x!=y bool Vrai si x et y sont de longueur différente ou si un item de x est différent d’un item de y. Faux sinon. x[i] item Retourne l’item en position i de x. Si i est strictement négatif, vaut x[len(x)+i] x[i:j] list Retourne la tranche d’items de la position i à la position j-1. x[:j] list Retourne la tranche d’items de la position 0 à la position j-1. x[i:] list Retourne la tranche d’items de la position i à la fin de la liste. iter(x) iterator Retourne un itérateur sur x repr(x) str Représentation officielle de x sous forme de chaîne de caractères

Aller vers Initiation interactive à Python : Défis de programmation - 1

Construire une suite #

Une utilisation courante des listes est de stocker les différentes termes d’une suite. Reprenons l’exemple de la suite de Fibonacci. Chaque terme est le somme des deux précédents et les deux premiers termes sont 0 et 1.

On peut initialiser la liste des termes ainsi :

fibo = [0, 1]

Le premier terme est :

>>> fibo[0]
0

et le second est :

>>> fibo[1]
1

Le terme suivant est la somme de fibo[0] et de fibo[1] :

>>> fibo[0] + fibo[1]
1

Pour ajouter cette nouvelle valeur en fin de liste, on peut utiliser append :

>>> fibo.append(fibo[0] + fibo[1])
>>> fibo
[0, 1, 1]

On peut continuer sur notre lancée :

>>> fibo.append(fibo[1] + fibo[2])
>>> fibo
[0, 1, 1, 2]

Voyez comme on calcule les 30 permiers termes de la suite en exécutant le programme suivant :

![](url>/SC/suite_fibo.php 100%,20em noscroll)

L’erreur la plus courante est certainement de se tromper dans les indices des éléments de la liste. Si par exemple vous indiquez fibo[i] + fibo[i-1] à la place de fibo[i-1] + fibo[i-2], ça ne fonctionnera plus. Essayez de bien comprendre pourquoi.
Les indices négatifs permettent d’accéder aux élément d’une liste en partant de la fin. L’indice -1 désigne le dernier élément, -2 l’avant dernier etc… Comme dans l’exemple précédent, nous voulons toujours sommer les deux derniers éléments ajoutés, on peut remplacer fibo[i-1] + fibo[i-2] par fibo[-1] + fibo[-2] ce qui veut littéralement dire : la somme des deux derniers éléments. À l’usage, c’est plus lisible.

Les nombres de Jacobsthal sont obtenus d’une manière presque identique aux nombre de Fibonacci. Nous avons aussi J(0)=0 et J(1)=1 mais ensuite, chaque nombre est obtenu comme la somme du nombre qui le précède par le double de celui qui le précède encore :

  • J(2) = J(1) + 2* J(0) = 1
  • J(3) = J(2) + 2* J(1) = 3

On obtient ainsi : 0, 1, 1, 3, 5, 11, 21…

Modifiez le programme qui précède pour calculer J(20). Vous devez trouver : 349525

Essayez de n’afficher que ce résultat, et non toute la suite.

Combien vaut J(60) ?

Initiation interactive à Python : Défis de programmation - 1 #

Résoudre des défis de programmation est un bon moyen de progresser rapidement. Nous proposons ici de détailler comment résoudre certains des problèmes disponibles sur PyDéfis. Là aussi, il existe beaucoup d’autres sites de ce type, francophones ou non.

Vous pouvez vous inscrire du PyDéfis si vous voulez pouvoir soumettre des solutions. Si vous voulez simplement consulter les énoncés, en revanche, pas besoin d’inscription.

Bien qu’ils ne soient pas très compliqués, les exercices proposés sur PyDéfis nécessitent généralement un peu plus de connaissances que ce que nous avons vu pour le moment. Il n’est donc pas inutile de se munir d’un tutoriel général sur Python, comme le document mentionné plus haut. D’autres explications seront données au fur et à mesure dans ce texte.

Programmer un algorithme #

Lien vers l’énoncé : Algorithme du professeur Guique

Ce premier exercice est facile et ne contient rien que nous n’ayons encore vu. Il s’agit simplement de traduire un calcul répétitif donné sous la forme d’un algorithme, en Python. Les variables a, b, c, i, et n doivent être initialisées à des valeurs d’entrées données comme entrées au problème. Ces valeurs peuvent varier. Supposons qu’elles sont égales à 1,2,4,1 et 0 :

a = 1
b = 2
c = 4
...

On peut faire plus court, car Python possède un opérateur pour faire «simultanément» plusieurs affectations :

a,b,c,i,n = 1,2,4,1,0

Il faut ensuite répéter le même bloc d’instructions, tant que i est inférieur à 1000-n, puis afficher les valeurs qui seront contenues dans a, b et c, ce qui constitue la réponse à la question :

while i < 1000 - n :
   BLOC À RÉPÉTER
print(a,b,c)

Le bloc à répéter ne contient que des affectation et des opérations élémentaires. Le contenu de ce bloc peut varier. Voici un exemple :

            a=b
            b=c+a
            c=(2)*c+(3)*a-b
            n=a+b
            augmenter i de 1

Donnera en Python :

            a = b
            b = c + a
            c = 2 * c + 3 * a - b
            n = a + b
            i = i + 1

Pour valider la réponse sur Pydéfis, il faut indiquer les 3 nombres séparés par des virgule.

Si vous tentez de valider l’exercice, vérifiez bien votre énoncé : opérations arithmétiques dans le bloc while et valeurs de départs. Ils peuvent varier par rapport à ce qui est proposé ici.

Premier particulier #

Lien vers l’énoncé : Premier particulier (1)

Dans ce défi, nous devons trouver les nombres de la forme (par exemple) 3k+7 où k est un nombre entier. Ces nombres sont : 3*0+7, 3*1+7, 3*2+7, 3*3+7, 3*4+7 etc… c’est à dire 7, 10, 13, 16, 19… Parmi les nombres obtenus (il y en a une infinité), certains sont des nombres premiers.

Les nombres premiers sont les nombres qui ne sont divisibles que par 1 et eux-mêmes. Une autre façon de voir les chose est de dire que si vous avez un nombre de morceaux de sucre qui est premier, vous ne pouvez pas les disposer, tous à plat, de manière à faire un rectangle, sauf en les mettant tous en ligne. Ainsi, 12 n’est pas premier, mais 11 est premier.

Prime rectangles, by Fredrik Johansson [Public domain], via
Wikimedia
Commons{.align-center}

Vous trouverez des informations complémentaires sur les nombres premiers ici : [Nombre Premier](https://fr.wikipedia.org/wiki/Nombre Premier).

Pour tester si on nombre est premier, nous pouvons essayer de le diviser successivement par 2, 3, 4, etc… Si une des division, par exemple la division par 6, tombe juste, cela signifie que le nombre est divisible par 6. Or dire qu’une division tombe juste c’est dire que le reste de la division est nul. Et nous avons justement un opérateur qui calcule le reste d’une division en Python : %.

Ainsi, pour savoir si le nombre n est premier, il suffit de calculer les restes des division de n par 2, puis 3, puis 4… jusqu’à n-1. Si un des restes est nul, le nombre n’est pas premier. Si aucun reste n’est nul, le nombre n est premier.

Il est possible d’améliorer cette idée, et arrêtant de calculer les restes plus tôt (on peut s’arrêter à l’arrondi par défaut de $\sqrt{n}$). Si vous savez comment faire, essayez. Sinon, ce n’st pas grave, nous pouvons résoudre le défi sans savoir ça…

Voyons d’abord comment tester si un nombre est premier :

n = 10
i = 2 
premier = True 
while i<n : 
    if n % i == 0 :
        premier = False
if premier :
    print("Le nombre",n,"est premier")
else :
    print("Le nombre",n,"n'est pas premier (il est composé)")

Il y a juste deux choses nouvelles dans ce programme, ce sont les valeurs True et False. Ces deux valeurs sont, en français : Vrai et Faux. Une variable qui peut valeoir Vrai ou Faux est une variable booléenne (comme il y a des variables entières, qui contiennent des entiers, il y a des variables booléennes, qui contiennent des booléens).

Le test final : if premier est une autre façon d’écrire if premier == True. Observez attentivement le programme. Voyez comme la valeur de premier est initialisée à True. Puis on procède à toutes les divisions. Et si une des divisions tombe juste, on passe premier à False. Après les tests, si premier est à False, c’est qu’au moins une des division est tombée juste, et donc que le nombre n’est pas premier.

Notre programme marche bien, mais si nous devons maintenant vérifier si plusieurs nombres sont premiers, il n’est pas facile à utiliser. Pour nous simplifier la vie, nous allons écrire notre première fonction. Pour l’instant nous pouvons considérer qu’écrire une fonction, c’est rajouter une nouvelle fonctionnalité à Python. Nous allons lui ajouter la possibilité de nous dire si n’importe quel nombre donné est premier. …

À suivre…