Introduction à Python P. Chassignet 31 janvier 2014 1/34 Organisation du modal Jean-Marc Steyaert et Philippe Chassignet 2/34 Organisation du modal Jean-Marc Steyaert et Philippe Chassignet février : initiation Python et Biopython, un peu de bio et d’algo 10h30 – 12h30 / 13h30 – 15h30 / 15h45 – 17h15 PhC PhC JMS ou 10h30 – 12h30 / 13h15 – 15h15 / 15h30 – 17h00 ? 2/34 Organisation du modal Jean-Marc Steyaert et Philippe Chassignet février : initiation Python et Biopython, un peu de bio et d’algo 10h30 – 12h30 / 13h30 – 15h30 / 15h45 – 17h15 PhC PhC JMS ou 10h30 – 12h30 / 13h15 – 15h15 / 15h30 – 17h00 ? mars, avril : projet — plus de bio et d’algo 2/34 Plan introduction bases strings listes tables fichiers 3/34 Plan 1 Python, les bases 2 Chaînes de caractères en Python 3 Tableaux dynamiques en Python 4/34 Python “le” langage de la bio-informatique ? 5/34 Python “le” langage de la bio-informatique ? Biopython (2000 ...), BioPerl (2002 ...), BioJava (2008 ...) 5/34 Python “le” langage de la bio-informatique ? Biopython (2000 ...), BioPerl (2002 ...), BioJava (2008 ...) Biopython = bon compromis, large communauté 5/34 Python “le” langage de la bio-informatique ? Biopython (2000 ...), BioPerl (2002 ...), BioJava (2008 ...) Biopython = bon compromis, large communauté Python 1989 (Guido van Rossum)... Python 2.0 2000 Python 3.0 2008 incompatibilités avec Python 2 (et BioPython !) 5/34 Python “le” langage de la bio-informatique ? Biopython (2000 ...), BioPerl (2002 ...), BioJava (2008 ...) Biopython = bon compromis, large communauté Python 1989 (Guido van Rossum)... Python 2.0 2000 Python 3.0 2008 incompatibilités avec Python 2 (et BioPython !) Python 2.7 2010 (le dernier de la série) ⇒ pour l’instant, Python (2.6 ou) 2.7, pas Python 3 http://docs.python.org/2/ http: //developers.google.com/edu/python/exercises/basic langage interprété (pas de compilation, portabilité) typage dynamique (à l’exécution) 5/34 Python : langage interprété dans une fenêtre console, lancer l’interpréteur : %python Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49) ... >>> 6/34 Python : langage interprété dans une fenêtre console, lancer l’interpréteur : %python Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49) ... >>> a=3 >>> 6/34 Python : langage interprété dans une fenêtre console, lancer l’interpréteur : %python Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49) ... >>> a=3 >>> a+1 4 >>> 6/34 Python : langage interprété dans une fenêtre console, lancer l’interpréteur : %python Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49) ... >>> a=3 >>> a+1 4 >>> type(a) <type ’int’> >>> 6/34 Python : langage interprété dans une fenêtre console, lancer l’interpréteur : %python Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49) ... >>> a=3 >>> a+1 4 >>> type(a) <type ’int’> >>> → typage dynamique → top-level → syntaxe simplifiée 6/34 Python : langage à objets >>> a=complex(1,2) >>> pas de new 7/34 Python : langage à objets >>> a=complex(1,2) >>> type(a) <type ’complex’> >>> pas de new 7/34 Python : langage à objets >>> a=complex(1,2) >>> type(a) <type ’complex’> >>> pas de new >>> a.real 1.0 >>> a.imag 2.0 >>> a.conjugate() (1-2j) 7/34 Python : langage à objets >>> a=complex(1,2) >>> type(a) <type ’complex’> >>> pas de new >>> a.real 1.0 >>> a.imag 2.0 >>> a.conjugate() (1-2j) >>> a=1+2j >>> a*a (-3+4j) >>> a+3 (4+2j) 7/34 la face cachée >>> dir(a) [... , ’__add__’, ..., ’__mul__’, ..., ’real’, ’imag’, ’conjugate’] >>> a.conjugate <built-in method conjugate of complex object at 0x1004290d0> >>> a.__add__ <method-wrapper ’__add__’ of complex object at 0x1004290d0> 8/34 la face cachée >>> dir(a) [... , ’__add__’, ..., ’__mul__’, ..., ’real’, ’imag’, ’conjugate’] >>> a.conjugate <built-in method conjugate of complex object at 0x1004290d0> >>> a.__add__ <method-wrapper ’__add__’ of complex object at 0x1004290d0> >>> b=4 >>> b.conjugate <built-in method conjugate of int object at 0x10020b1f0> 8/34 la face cachée >>> dir(a) [... , ’__add__’, ..., ’__mul__’, ..., ’real’, ’imag’, ’conjugate’] >>> a.conjugate <built-in method conjugate of complex object at 0x1004290d0> >>> a.__add__ <method-wrapper ’__add__’ of complex object at 0x1004290d0> >>> b=4 >>> b.conjugate <built-in method conjugate of int object at 0x10020b1f0> >>> type(1.0) <type ’float’> >>> dir(1.0) ... 8/34 la face cachée >>> dir(a) [... , ’__add__’, ..., ’__mul__’, ..., ’real’, ’imag’, ’conjugate’] >>> a.conjugate <built-in method conjugate of complex object at 0x1004290d0> >>> a.__add__ <method-wrapper ’__add__’ of complex object at 0x1004290d0> >>> b=4 >>> b.conjugate <built-in method conjugate of int object at 0x10020b1f0> >>> type(1.0) <type ’float’> >>> dir(1.0) ... → les valeurs sont typées (pas les variables) 8/34 curiosités >>> (1.0).is_integer() True >>> type((1.0).is_integer()) <type ’bool’> 9/34 curiosités >>> (1.0).is_integer() True >>> type((1.0).is_integer()) <type ’bool’> >>> a=’toto’ >>> a+3 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: cannot concatenate ’str’ and ’int’ objects 9/34 curiosités >>> (1.0).is_integer() True >>> type((1.0).is_integer()) <type ’bool’> >>> a=’toto’ >>> a+3 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: cannot concatenate ’str’ and ’int’ objects >>> a+str(3) ’toto3’ 9/34 curiosités >>> (1.0).is_integer() True >>> type((1.0).is_integer()) <type ’bool’> >>> a=’toto’ >>> a+3 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: cannot concatenate ’str’ and ’int’ objects >>> a+str(3) ’toto3’ >>> 3*a ’totototototo’ 9/34 Mise en oeuvre de programmes 2ème fenêtre : éditeur de texte écrire le fichier hello.py (pour l’instant 1 ligne): print ’Hello’+’World’ 10/34 Mise en oeuvre de programmes 2ème fenêtre : éditeur de texte écrire le fichier hello.py (pour l’instant 1 ligne): print ’Hello’+’World’ 3ème fenêtre: console %python hello.py ... 10/34 Mise en oeuvre de programmes 2ème fenêtre : éditeur de texte écrire le fichier hello.py (pour l’instant 1 ligne): print ’Hello’+’World’ 3ème fenêtre: console %python hello.py ... sous Unix : 10/34 Mise en oeuvre de programmes 2ème fenêtre : éditeur de texte écrire le fichier hello.py (pour l’instant 1 ligne): print ’Hello’+’World’ 3ème fenêtre: console %python hello.py ... sous Unix : %chmod +x hello.py 10/34 Mise en oeuvre de programmes 2ème fenêtre : éditeur de texte écrire le fichier hello.py (pour l’instant 1 ligne): print ’Hello’+’World’ 3ème fenêtre: console %python hello.py ... sous Unix : %chmod +x hello.py dans le fichier hello.py: #!/usr/bin/python print ’Hello’+’World’ (ou #!/usr/local/bin/python2.6 ...) 10/34 Mise en oeuvre de programmes 2ème fenêtre : éditeur de texte écrire le fichier hello.py (pour l’instant 1 ligne): print ’Hello’+’World’ 3ème fenêtre: console %python hello.py ... sous Unix : %chmod +x hello.py dans le fichier hello.py: #!/usr/bin/python print ’Hello’+’World’ (ou #!/usr/local/bin/python2.6 ...) %./hello.py 10/34 print : quelques variantes print print print print print print print print ’Hello’+’World’ ’Hello’+"World" ’Hello’ ’World’ ’Hello’ ’World’; ’Hello’,’World’ ’Hello’, ’World’ ’Hello’,; print ’World’ # # # # # # # # concaténation explicite ’ ou " concaténation automatique ; facultatif (séparateur) 2 arguments --> espace pas de retour à la ligne met l’espace là, il faut consulter ! 11/34 Programme Python : façon (presque) “pro” #!/usr/bin/python def main(): print ’Hello ’+’World’ if __name__ == ’__main__’: main() 12/34 Programme Python : façon (presque) “pro” #!/usr/bin/python def main(): print ’Hello ’+’World’ if __name__ == ’__main__’: main() def définit une fonction (attention au :) 12/34 Programme Python : façon (presque) “pro” #!/usr/bin/python def main(): print ’Hello ’+’World’ if __name__ == ’__main__’: main() def définit une fonction (attention au :) main = nom conventionnel pour la fonction initiale 12/34 Programme Python : façon (presque) “pro” #!/usr/bin/python def main(): print ’Hello ’+’World’ if __name__ == ’__main__’: main() def définit une fonction (attention au :) main = nom conventionnel pour la fonction initiale pas d’accolade, indentation obligatoire 12/34 Programme Python : façon (presque) “pro” #!/usr/bin/python def main(): print ’Hello ’+’World’ if __name__ == ’__main__’: main() def définit une fonction (attention au :) main = nom conventionnel pour la fonction initiale pas d’accolade, indentation obligatoire NEWLINE, INDENT et DEDENT font partie de la syntaxe 12/34 Programme Python : façon (presque) “pro” #!/usr/bin/python def main(): print ’Hello ’+’World’ if __name__ == ’__main__’: main() def définit une fonction (attention au :) main = nom conventionnel pour la fonction initiale pas d’accolade, indentation obligatoire NEWLINE, INDENT et DEDENT font partie de la syntaxe if expression : 12/34 Programme Python : façon (presque) “pro” #!/usr/bin/python def main(): print ’Hello ’+’World’ if __name__ == ’__main__’: main() def définit une fonction (attention au :) main = nom conventionnel pour la fonction initiale pas d’accolade, indentation obligatoire NEWLINE, INDENT et DEDENT font partie de la syntaxe if expression : __name__ == ’__main__’ est vrai ssi on lance hello.py 12/34 Programme Python : façon (presque) “pro” #!/usr/bin/python def main(): print ’Hello ’+’World’ if __name__ == ’__main__’: main() def définit une fonction (attention au :) main = nom conventionnel pour la fonction initiale pas d’accolade, indentation obligatoire NEWLINE, INDENT et DEDENT font partie de la syntaxe if expression : __name__ == ’__main__’ est vrai ssi on lance hello.py 6= charger le module hello.py 12/34 Python : fonctions #!/usr/bin/python def hello(name): print ’Hello ’+name def who(): return ’World’ def main(): hello(who()) if __name__ == ’__main__’: main() 13/34 Python : fonctions #!/usr/bin/python def hello(name): print ’Hello ’+name def who(): return ’World’ def main(): hello(who()) if __name__ == ’__main__’: main() lignes vides importantes ? 13/34 Python : fonctions #!/usr/bin/python def hello(name): print ’Hello ’+name def who(): return ’World’ def main(): hello(who()) if __name__ == ’__main__’: main() lignes vides importantes ? ≡ besoin du DEDENT 13/34 Python : conditionnelles if expression : elif expression : else : 14/34 Python : conditionnelles if expression : elif expression : else : attention à l’indentation 14/34 Python : conditionnelles if expression : elif expression : else : attention à l’indentation if a>=0: if a==0: print ’zero’ else: print ’positif’ 14/34 Python : conditionnelles if expression : elif expression : else : attention à l’indentation if a>=0: if a==0: print ’zero’ else: print ’positif’ if a>=0: if a==0: print ’zero’ else: print ’negatif’ 14/34 Python : conditionnelles if expression : elif expression : else : attention à l’indentation if a>=0: if a==0: print ’zero’ else: print ’positif’ if a>=0: if a==0: print ’zero’ else: print ’negatif’ danger : mélange de tabulations et d’espaces 14/34 Python : conditionnelles if expression : elif expression : else : attention à l’indentation if a>=0: if a==0: print ’zero’ else: print ’positif’ if a>=0: if a==0: print ’zero’ else: print ’negatif’ danger : mélange de tabulations et d’espaces → #!/usr/bin/python -tt 14/34 Python : expressions booléennes False et assimilés : None, zéros numériques, chaîne vide (ie. ”) et conteneurs vides 15/34 Python : expressions booléennes False et assimilés : None, zéros numériques, chaîne vide (ie. ”) et conteneurs vides True et assimilés = tout le reste 15/34 Python : expressions booléennes False et assimilés : None, zéros numériques, chaîne vide (ie. ”) et conteneurs vides True et assimilés = tout le reste x < y <= z préférable à x < y and y <= z, évalue une seule fois y (+ évaluation “paresseuse” de z) 15/34 Python : expressions booléennes False et assimilés : None, zéros numériques, chaîne vide (ie. ”) et conteneurs vides True et assimilés = tout le reste x < y <= z préférable à x < y and y <= z, évalue une seule fois y (+ évaluation “paresseuse” de z) x < y > z peu lisible mais autorisé 15/34 Python : expressions booléennes False et assimilés : None, zéros numériques, chaîne vide (ie. ”) et conteneurs vides True et assimilés = tout le reste x < y <= z préférable à x < y and y <= z, évalue une seule fois y (+ évaluation “paresseuse” de z) x < y > z peu lisible mais autorisé attention : not a == b est compris comme not ( a == b ) 15/34 Python : expressions booléennes False et assimilés : None, zéros numériques, chaîne vide (ie. ”) et conteneurs vides True et assimilés = tout le reste x < y <= z préférable à x < y and y <= z, évalue une seule fois y (+ évaluation “paresseuse” de z) x < y > z peu lisible mais autorisé attention : not a == b est compris comme not ( a == b ) == ≡ equals de Java is ≡ == de Java 15/34 Python : expressions booléennes False et assimilés : None, zéros numériques, chaîne vide (ie. ”) et conteneurs vides True et assimilés = tout le reste x < y <= z préférable à x < y and y <= z, évalue une seule fois y (+ évaluation “paresseuse” de z) x < y > z peu lisible mais autorisé attention : not a == b est compris comme not ( a == b ) == ≡ equals de Java is ≡ == de Java “if ternaire”, exemple : print ’impair’ if n%2 else ’pair’ 15/34 Python : expressions booléennes False et assimilés : None, zéros numériques, chaîne vide (ie. ”) et conteneurs vides True et assimilés = tout le reste x < y <= z préférable à x < y and y <= z, évalue une seule fois y (+ évaluation “paresseuse” de z) x < y > z peu lisible mais autorisé attention : not a == b est compris comme not ( a == b ) == ≡ equals de Java is ≡ == de Java “if ternaire”, exemple : print ’impair’ if n%2 else ’pair’ curiosités : != préférable à <> s or ’glop’ ? True+1 Hum ! 15/34 boucle while while expression : corps indenté 16/34 boucle while while expression : corps indenté classique : continue et break 16/34 boucle while while expression : corps indenté classique : continue et break particulier : while ... else : a = 111 i = 0 while i < 10: if i == a: print a,’found’ break i += 1 else: print a,’not found’ 16/34 boucle while while expression : corps indenté classique : continue et break particulier : while ... else : a = 111 i = 0 while i < 10: if i == a: print a,’found’ break i += 1 else: print a,’not found’ pas de do ... while 16/34 boucle for for variable in itérable : corps indenté 17/34 boucle for for variable in itérable : corps indenté chaîne = itérable = séquence de caractères : for c in ’toto’: print c 17/34 boucle for for variable in itérable : corps indenté chaîne = itérable = séquence de caractères : for c in ’toto’: print c séquences d’entiers : for i in range(...) >>> [0, >>> [2, >>> [5, >>> [5, range(10) 1, 2, 3, 4, 5, 6, 7, 8, 9] range(2,8,3) 5] range(5,1,-2) 3] range(5,0,-2) 3, 1] # impl. (0,10,1) 17/34 boucle for suite en Python 2, il faut préférer : for i in xrange(...) 18/34 boucle for suite en Python 2, il faut préférer : for i in xrange(...) expansion : range construit explicitement la séquence (complète) 18/34 boucle for suite en Python 2, il faut préférer : for i in xrange(...) expansion : range construit explicitement la séquence (complète) évaluation “paresseuse” : xrange construit un itérateur 18/34 boucle for suite en Python 2, il faut préférer : for i in xrange(...) expansion : range construit explicitement la séquence (complète) évaluation “paresseuse” : xrange construit un itérateur for x in range(1000000): continue # 0.076634 s for x in range(1000000): break # 0.028860 s for x in xrange(1000000): continue # 0.046771 s for x in xrange(1000000): break # 0.001214 s 18/34 Plan 1 Python, les bases 2 Chaînes de caractères en Python 3 Tableaux dynamiques en Python 19/34 Le type chaîne str 2 constructions littérales ’...’ ou "..." 20/34 Le type chaîne str 2 constructions littérales ’...’ ou "..." variante unicode : u’...’ ou u"..." voir la doc et tester 20/34 Le type chaîne str 2 constructions littérales ’...’ ou "..." variante unicode : u’...’ ou u"..." voir la doc et tester chaînes non mutables −→ toute modification (potentielle) construit une nouvelle chaîne 20/34 Le type chaîne str 2 constructions littérales ’...’ ou "..." variante unicode : u’...’ ou u"..." voir la doc et tester chaînes non mutables −→ toute modification (potentielle) construit une nouvelle chaîne opérateurs + et * 20/34 Le type chaîne str 2 constructions littérales ’...’ ou "..." variante unicode : u’...’ ou u"..." voir la doc et tester chaînes non mutables −→ toute modification (potentielle) construit une nouvelle chaîne opérateurs + et * + nombreuses autres méthodes doc + pratique (exercices) 20/34 Le type chaîne str 2 constructions littérales ’...’ ou "..." variante unicode : u’...’ ou u"..." voir la doc et tester chaînes non mutables −→ toute modification (potentielle) construit une nouvelle chaîne opérateurs + et * + nombreuses autres méthodes doc + pratique (exercices) ex. : >>> a = "TITI" >>> a.lower() ’titi’ >>> a ’TITI’ 20/34 Le type chaîne str 2 constructions littérales ’...’ ou "..." variante unicode : u’...’ ou u"..." voir la doc et tester chaînes non mutables −→ toute modification (potentielle) construit une nouvelle chaîne opérateurs + et * + nombreuses autres méthodes doc + pratique (exercices) ex. : >>> a = "TITI" >>> a.lower() ’titi’ >>> a ’TITI’ prédicats in et not in, voir aussi find 20/34 Sélection d’un caractère sélection du ième élément par [i] 21/34 Sélection d’un caractère sélection du ième élément par [i] pas de type char comme en Java → chaîne de longueur 1 21/34 Sélection d’un caractère sélection du ième élément par [i] pas de type char comme en Java → chaîne de longueur 1 >>> s = "Python" >>> s[0] ’P’ >>> s[5] ’n’ >>> s[-1] ’n’ >>> s[6] ... IndexError: string index out of range >>> s[2] = ’X’ ... TypeError: ’str’ object does not support item assignment 21/34 Découpage d’une chaîne (“slicing”) extraction de la “tranche” entre i et j-1 par [i:j] >>> s = "Python" >>> s[1:3] ’yt’ >>> s[1:] ’ython’ >>> s[:3] ’Pyt’ >>> s[:] ’Python’ >>> s[-2:] ’on’ >>> s[:-2] ’Pyth’ >>> s[:999] ’Python’ >>> s[3:2] ’’ >>> s[1000:1001] ’’ 22/34 Chaîne de formatage “à la C” utilise l’opérateur % syntaxe 1 : chaîne_format % valeur syntaxe 2 : chaîne_format % valeurs valeurs = “tuple” 23/34 Chaîne de formatage “à la C” utilise l’opérateur % syntaxe 1 : chaîne_format % valeur syntaxe 2 : chaîne_format % valeurs valeurs = “tuple” exemple : >>> import math >>> print math.pi 3.14159265359 >>> from math import pi as PI >>> print PI 3.14159265359 >>> print "%f" % PI 3.141593 >>> print "%3s = %f ou %.3f ou %.15f" % (’PI’, PI, PI, PI) PI = 3.141593 ou 3.142 ou 3.141592653589793 23/34 Chaîne de formatage “à la C” utilise l’opérateur % syntaxe 1 : chaîne_format % valeur syntaxe 2 : chaîne_format % valeurs valeurs = “tuple” exemple : >>> import math >>> print math.pi 3.14159265359 >>> from math import pi as PI >>> print PI 3.14159265359 >>> print "%f" % PI 3.141593 >>> print "%3s = %f ou %.3f ou %.15f" % (’PI’, PI, PI, PI) PI = 3.141593 ou 3.142 ou 3.141592653589793 énormément de possibilités voir la doc 23/34 Chaînes, remarques et curiosités on évite d’écrire for i in range(len(s)) : ... s[i] ... on écrit plutôt for c in s : ... c ... 24/34 Chaînes, remarques et curiosités on évite d’écrire for i in range(len(s)) : ... s[i] ... on écrit plutôt for c in s : ... c ... “generalized slicing” (cf. range) >>> s = "Python" >>> s[::2] ’Pto’ >>> s[1::2] ’yhn’ >>> s[::-1] ’nohtyP’ >>> s[::-2] ’nhy’ 24/34 Plan 1 Python, les bases 2 Chaînes de caractères en Python 3 Tableaux dynamiques en Python 25/34 Tableaux ≡ le type list 26/34 Tableaux ≡ le type list construction littérale entre [ et ], construction par + et * : 26/34 Tableaux ≡ le type list construction littérale entre [ et ], construction par + et * : >>> >>> [1, >>> >>> [0, >>> [0, >>> 1 >>> [1, maliste = [ 1, "beurk", 2 ] maliste ’beurk’, 2] maliste = [0, maliste] maliste [1, ’beurk’, 2]] maliste+[’suite’] [1, ’beurk’, 2], ’suite’] maliste[1][0] maliste[1]*3 ’beurk’, 2, 1, ’beurk’, 2, 1, ’beurk’, 2] 26/34 Tableaux ≡ le type list construction littérale entre [ et ], construction par + et * : >>> >>> [1, >>> >>> [0, >>> [0, >>> 1 >>> [1, maliste = [ 1, "beurk", 2 ] maliste ’beurk’, 2] maliste = [0, maliste] maliste [1, ’beurk’, 2]] maliste+[’suite’] [1, ’beurk’, 2], ’suite’] maliste[1][0] maliste[1]*3 ’beurk’, 2, 1, ’beurk’, 2, 1, ’beurk’, 2] [i] en O(1) = tableau dynamique ≡ ArrayList de Java 26/34 Tableaux ≡ le type list construction littérale entre [ et ], construction par + et * : >>> >>> [1, >>> >>> [0, >>> [0, >>> 1 >>> [1, maliste = [ 1, "beurk", 2 ] maliste ’beurk’, 2] maliste = [0, maliste] maliste [1, ’beurk’, 2]] maliste+[’suite’] [1, ’beurk’, 2], ’suite’] maliste[1][0] maliste[1]*3 ’beurk’, 2, 1, ’beurk’, 2, 1, ’beurk’, 2] [i] en O(1) = tableau dynamique ≡ ArrayList de Java mutables 26/34 list = séquence mutable >>> >>> >>> [1, >>> >>> [1, >>> >>> [1, >>> >>> [1, maliste = [1,2,3] maliste[1] = 0 maliste 0, 3] maliste.append(2) maliste 0, 3, 2] maliste.append([4,5]) maliste 0, 3, 2, [4, 5]] maliste.extend([6, 7]) maliste 0, 3, 2, [4, 5], 6, 7] # en O(1) # en O(1) amorti # attention piège # concaténation de 2 listes 27/34 list = séquence mutable >>> >>> >>> [1, >>> >>> [1, >>> >>> [1, >>> >>> [1, maliste = [1,2,3] maliste[1] = 0 maliste 0, 3] maliste.append(2) maliste 0, 3, 2] maliste.append([4,5]) maliste 0, 3, 2, [4, 5]] maliste.extend([6, 7]) maliste 0, 3, 2, [4, 5], 6, 7] + nombreuses méthodes # en O(1) # en O(1) amorti # attention piège # concaténation de 2 listes doc + pratique (exercices) 27/34 Modifications par “slice assignment” >>> [1, >>> >>> [1, >>> >>> [1, >>> >>> [1, >>> >>> [1, >>> >>> [] maliste 0, 3, 2, [4, 5], 6, 7] maliste[3:5] = [] # suppressions maliste 0, 3, 6, 7] maliste[2:2] = [4,5] # insertions maliste 0, 4, 5, 3, 6, 7] maliste[1:5] = [2,3,4] # combiné maliste 2, 3, 4, 6, 7] maliste[:0] = maliste # insertion en tête, hum ! maliste 2, 3, 4, 6, 7, 1, 2, 3, 4, 6, 7] # ouf ! mais ... maliste[:] = [] maliste 28/34 Opérations diverses type list utilisable comme une pile, en O(1) : >>> >>> >>> [1, >>> 4 >>> [1, maliste = [1,2,3] maliste.append(4) maliste 2, 3, 4] maliste.pop() maliste 2, 3] 29/34 Opérations diverses type list utilisable comme une pile, en O(1) : >>> >>> >>> [1, >>> 4 >>> [1, maliste = [1,2,3] maliste.append(4) maliste 2, 3, 4] maliste.pop() maliste 2, 3] mais attention utilisation comme file coûteuse : en O(n) 29/34 Opérations diverses type list utilisable comme une pile, en O(1) : >>> >>> >>> [1, >>> 4 >>> [1, maliste = [1,2,3] maliste.append(4) maliste 2, 3, 4] maliste.pop() maliste 2, 3] mais attention utilisation comme file coûteuse : en O(n) → type deque ≡ LinkedList de Java 29/34 Opérations diverses type list utilisable comme une pile, en O(1) : >>> >>> >>> [1, >>> 4 >>> [1, maliste = [1,2,3] maliste.append(4) maliste 2, 3, 4] maliste.pop() maliste 2, 3] mais attention utilisation comme file coûteuse : en O(n) → type deque ≡ LinkedList de Java sort et reverse “en place” 29/34 Partage >>> >>> >>> >>> >>> [1, >>> [1, a = [1,2,3] b = a c = a[:] a[1] = 0 b 0, 3] c 2, 3] # même référence # copie 30/34 Partage >>> >>> >>> >>> >>> [1, >>> [1, a = [1,2,3] b = a c = a[:] a[1] = 0 b 0, 3] c 2, 3] >>> a = [[1,2,3]] >>> c = a[:] # même référence # copie # ou a = [a] # copie superficielle # = copie de la référence à [1,2,3] >>> a[0][1] = 0 >>> c [[1, 0, 3]] 30/34 Partage, suite >>> maliste = [[]] * 3 >>> maliste [[], [], []] >>> maliste[0].append(’x’) >>> maliste [[’x’], [’x’], [’x’]] 31/34 Partage, suite >>> maliste = [[]] * 3 >>> maliste [[], [], []] >>> maliste[0].append(’x’) >>> maliste [[’x’], [’x’], [’x’]] >>> maliste = [[]] + [[]] >>> maliste[0].append(’x’) >>> maliste [[’x’], []] 31/34 Partage, suite >>> maliste = [[]] * 3 >>> maliste [[], [], []] >>> maliste[0].append(’x’) >>> maliste [[’x’], [’x’], [’x’]] >>> maliste = [[]] + [[]] >>> maliste[0].append(’x’) >>> maliste [[’x’], []] partage de structures mutables = danger 31/34 Listes infinies >>> maliste = [1,2,3] >>> maliste[:0] = [maliste] # rem: sans [ ] OK >>> maliste [[...], 1, 2, 3] >>> maliste[0][0][0][0] [[...], 1, 2, 3] >>> maliste[0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][ [[...], 1, 2, 3] >>> >>> >>> [1, maliste = [1,2,3] maliste.append(maliste) maliste 2, 3, [...]] # rem: avec extend OK 32/34 Listes infinies >>> maliste = [1,2,3] >>> maliste[:0] = [maliste] # rem: sans [ ] OK >>> maliste [[...], 1, 2, 3] >>> maliste[0][0][0][0] [[...], 1, 2, 3] >>> maliste[0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][ [[...], 1, 2, 3] >>> >>> >>> [1, maliste = [1,2,3] maliste.append(maliste) maliste 2, 3, [...]] # rem: avec extend OK Le typage aurait évité cela ! 32/34 Liste en compréhension exemple : >>> >>> [0, >>> [0, maliste = range(10) maliste 1, 2, 3, 4, 5, 6, 7, 8, 9] [ x*x for x in maliste ] 1, 4, 9, 16, 25, 36, 49, 64, 81] équivalent à : result = [] for x in maliste: result.append(x*x) 33/34 Liste en compréhension exemple : >>> >>> [0, >>> [0, maliste = range(10) maliste 1, 2, 3, 4, 5, 6, 7, 8, 9] [ x*x for x in maliste ] 1, 4, 9, 16, 25, 36, 49, 64, 81] équivalent à : result = [] for x in maliste: result.append(x*x) autres exemples : >>> [ x*y for y in [1,2,3] for x in [-1,1] ] [-1, 1, -2, 2, -3, 3] >>> [ x*y for x in [-1,1] for y in [1,2,3] if y%2==1 ] [-1, -3, 1, 3] 33/34 Listes, remarques et curiosités >>> maliste [0, [1, ’beurk’, 2]] >>> 0 in maliste True >>> 1 in maliste False >>> [1, ’beurk’, 2] in maliste True 34/34 Listes, remarques et curiosités >>> maliste [0, [1, ’beurk’, 2]] >>> 0 in maliste True >>> 1 in maliste False >>> [1, ’beurk’, 2] in maliste True for i in range(len(maliste)) : ... maliste[i] ... for e in maliste : ... e ... for i, e in enumerate(maliste) : ... i ... e ... 34/34 Listes, remarques et curiosités >>> maliste [0, [1, ’beurk’, 2]] >>> 0 in maliste True >>> 1 in maliste False >>> [1, ’beurk’, 2] in maliste True for i in range(len(maliste)) : ... maliste[i] ... for e in maliste : ... e ... for i, e in enumerate(maliste) : ... i ... e ... voir reduce, join 34/34 Listes, remarques et curiosités >>> maliste [0, [1, ’beurk’, 2]] >>> 0 in maliste True >>> 1 in maliste False >>> [1, ’beurk’, 2] in maliste True for i in range(len(maliste)) : ... maliste[i] ... for e in maliste : ... e ... for i, e in enumerate(maliste) : ... i ... e ... voir reduce, join >>> "".join([’a’,’b’,’c’]) ’abc’ >>> list("glop") # constructeur list(séquence) [’g’, ’l’, ’o’, ’p’] 34/34