• Aucun résultat trouvé

CHAPITRE 3 Structures de contrôle

3.5. Les techniques de boucles

Les types numériques mélangés sont comparés en fonction de leur valeur numérique, ainsi 0 est égal à 0.0, etc.

3.5. Les techniques de boucles

Certaine techniques de boucles sont particulières à Python et très utiles. On en présente ici quelques unes.

3.5.1. La fonction range(). Permet de parcourir une liste d’entiers régulièrement espacés.

Elle génère un itérateur sur une progression arithmétique. Syntaxe :

range([a,] b [, s])

Les paramètres a, bet sdoivent être entiers (positifs ou négatifs), sdoit être non nul. Si s est nul, l’exceptionValueErrorest levée. Renvoi un itérateur sur la liste2des entiers ni = a + is où 06 i 6 int(b−as ).

Pour obtenir une liste plutôt qu’un itérateur, il faut le demander explicitement :

1 >>> range(0, 100, 10)

2 range(0, 100, 10)

3 >>> list(range(0,100,10))

4 [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]

L’intérêt de renvoyer un itérateur, plutôt que la liste intégrale, est évident en terme d’encom- brement mémoire. Les éléments de l’itérateur sont calculés à la demande et la liste n’est jamais intégralement construite, sauf si, comme c’est le cas ci-dessus, on le demande explicitement. Voici une utilisation typique de la fonctionrange()avec une bouclefor

1 >>> for x in range(3) :

2 ... print (x, end = ',')

3 0,1,2,

2EnPython2 la fonction

3.5.2. Les méthodes dict.keys(), dict.values() et dict.items(). Dans l’ordre où elles sont

citées, ces méthodes renvoient un itérateur sur les clés, sur les valeurs ou bien sur les items (clé,valeur) du dictionnaire. On peut ensuite boucler sur ces itérateurs.

1 >>> prefectures = {'PA' : 'Pau', 'HP' : 'Tarbes','PO' :'Perpignan' }

2 >>> for dpt, pref in prefectures.items() :

3 ... print (dpt,pref)

4 ...

5 HP Tarbes

6 PO Perpignan

7 PA Pau

3.5.3. La fonction enumerate(). Lorsqu’on boucle sur une séquence, on peut obtenir simul-

tanément l’indice et la valeur d’un élément en utilisant la fonctionenumerate(). Syntaxe :

enumerate(L)

Ldoit être un itérable (séquence, ...). Renvoi un itérateur sur les couples (index,valeur) de l’ité- rableL

1 >>> a = ['tic', 'tac', 'toe']

2 >>> for i, val in enumerate(a) :

3 ... print (i, val)

Cette construction est préférable (plus rapide) à :

1 >>> for i in range(len(a)) :

2 ... print (i,a[i])

3.5.4. La fonction zip(). Pour boucler sur deux séquences, ou plus, en même temps, les

éléments peuvent être appariés avec la fonctionzip(). Syntaxe :

zip(i1, i2, ...)

i1, i2, ... sont des itérables. Renvoie un itérateur qui parcourt la liste de tuples (v1,v2,...) constitués d’un élément de chaque argument. Les arguments i1,i2, ... ne sont pas nécessairement de même longueur, la longueur du résultat estmin(len(i1), len(i2),...)

3.5 Les techniques de boucles 67

1 >>> questions = ['nom', 'caracteristique', 'sport favori','autre']

2 >>> answers = ['charma','mutant', 'escalade']

3 >>> for q, a in zip(questions, answers) :

4 ... print ('quel est votre',q, ' ?', a)

5 ...

6 quel est votre nom ? charma

7 quel est votre caracteristique ? mutant

8 quel est votre sport favori ? escalade

3.5.5. La fonction reversed(). Pour boucler à l’envers sur une séquence, spécifiez d’abord

la séquence à l’endroit, ensuite appelez la fonctionreversed().

1 >>> for i in reversed(range(1,10,2)) :

2 ... print i

3.5.6. La fonction sorted(). Pour boucler sur une séquence comme si elle était triée, uti-

lisez la fonctionsorted() qui retourne une nouvelle séquence triée tout en laissant la source inchangée.

1 >>> phrase = ['La', 'liste', 'suivante', 'énumère', 'les',

2 'plantes', 'couramment', 'consommées',

3 'comme', 'légumes']

4 >>> for word in sorted(phrase) :

5 ... print word

3.5.7. La fonction map(). Permet de créer une liste en appliquant une fonction sur toutes

les valeurs renvoyées par un itérateur. Syntaxe :

map(f, it)

itest un itérable (séquence, dictionnaire, fichier, ...). fest une fonction qui prend en argument les items deit. Retourne l’itérateur sur les valeursf(i)pouriparcourantit.

1 >>> def f(x) : return 2*x

2 >>> map(f, range(5))

3 <map object at 0x9ff9aec>

4 >>> list(_)

map()renvoie un objetmapque l’on peut ensuite transformer en liste, c’est l’objet de l’instruction list(_)la variable'_'désigne le dernier objet calculé.

3.5.8. La fonction filter(). Permet la création de liste après application d’une fonction fil-

trante. Syntaxe :

filter(f, It)

fest une fonction filtre qui doit renvoyerTrueouFalse, etItun itérateur.

Renvoi un itérateur constitué de tous les item x de It qui vérifie f(x)== True est passé en argument à la fonction filtrante.

1 >>> def f(x) : return x<3

2 >>> filter(f,range(10))

3 <filter object at 0x8669ecc>

4 >>> list(_)

5 [0, 1, 2]

La première ligne définit la fonctionf()qui renvoie la valeur (TrueouFalse) de l’expression booléennex<3. L’application de la fonction filter()avec comme argument le filtref() et la liste (en fait l’itérateur)range(10)renvoie un objet de type filter qu’il suffit de transformer en liste.

Les programmeurs venant de langages plus traditionnels, comme leC++ou leC, sont souvent surpris par ces facilités offertes parPython , et « oublient » de les utiliser... du moins dans un premier temps.

3.5.9. Les list comprehension. Les list comprehension3 fournissent une façon concise de créer des listes sans avoir recours àmap(),filter()et/oulambda. Chaque list comprehension consiste en une expression suivie d’une clause for, puis zéro ou plus clauses for ou if. Le résultat sera une liste résultant de l’évaluation de l’expression dans le contexte des clausesforet ifqui la suivent. Si l’expression s’évalue en un tuple, elle doit être mise entre parenthèses. Voici quelques exemples d’utilisation :

1 >>> entiers = range(5)

2 >>> reels=[float(i) for i in entiers]

3On trouve diverses traductions de list comprehension dans la littérature.

– « compréhension de liste » est un contresens – « listes compréhensives » également

J’adopterai ici « listes en compréhension », par opposition aux « listes en extension », lorsque tous les éléments de la liste sont cités explicitement.

3.5 Exercices 69 La liste reels résultante est analogue à la liste entiers, dans laquelle chaque élément a été transformé en (float)

Testez les instructions suivantes :

1 >>> vec,vec1 = [2, 4, 6],[8,9,12]

2 >>> [3*x for x in vec]

3 [6, 12, 18]

4 >>> [3*x for x in vec if x > 3]

5 [12, 18]

6 >>> [v[0]*v[1] for v in zip(vec,vec1)]

7 [16, 36, 72] 8 >>> [3*x for x in vec if x < 2] 9 [] 10 >>> [{x : x**2} for x in vec] 11 [{2 : 4}, {4 : 16}, {6 : 36}] 12 >>> [[x,x**2] for x in vec] 13 [[2, 4], [4, 16], [6, 36]]

14 >>> [x, x**2 for x in vec] # erreur 15 SyntaxError : invalid syntax

16 >>> [(x, x**2) for x in vec]

17 [(2, 4), (4, 16), (6, 36)]

18 >>> [x*y for x in vec for y in vec1]

19 [16, 18, 24, 32, 36, 48, 48, 54, 72]

20 >>> [vec[i]*vec1[i] for i in range(len(vec))]

21 [16, 36, 72]

Exercices

Exercice 15. Déterminez à l’aide d’une bouclewhilele plus petit réel strictement positif de la

Documents relatifs