Débuter et progresser avec la programmation PYTHON
La syntaxe Python
Guillaume Wisniewski septembre 2010
Résumé
Ce document a pour objectif de présenter rapidement la syntaxe de Python ainsi que certaines constructions et bibliothèques que nous utiliserons dans ce cours. Une introduction plus détaillée au langage est disponible à l’url
Table des matières
1 Exécuter un programme python
Il y a deux manière d’exécuter un programme python :
– soit en sauvegardant le programme dans un fichier (ayant généralement l’extension .py) et en exécutant la commande : python .
– soit en utilisant directement l’interpréteur : en lan¸cant le programme python il est possible d’entrer directement des commandes qui seront exécutées au fur et à mesure de leur saise.
Dans les exemples de ce document, nous utiliserons cette dernière méthode : les lignes commen¸cant par In [1]: correspondent aux commandes qui sont saisies et les autres aux « réponses » de l’interpréteur.
2 Types standards
2.1 Type de base
Python est un langage typé dynamiquement : le type d’une variable est déterminé par l’interpréteur au moment de l’exécution et n’a pas besoin d’être déclaré :
| In [17]: a = 1 # a est de type integer In [18]: b = 2.0 # b est de type float In [19]: a = "le chat" # a est maitenant de type string In [1]: c = 3 + 2j # nombre complexes In [2]: print c Out[2]: (3+2j) In [3]: d = 1 == 2 # booléens In [4]: d # dans l’interpréteur, le print n’est pas obligatoire Out[4]: False In [1]: e, f = 3, 2.1 |
On remarquera que :
– le marqueur de fin de ligne est le retour chariot et non le point virgule comme dans la plupart des autres langage;
– le caractère # permet d’indiquer un commentaire;
– il est possible d’effectuer plusieurs assignations simultanément.
2.2 Collections
Python fournit de manière standard différents types de collections. Chacune de ces collections est un objet et il est donc possible d’utiliser les méthodes d’exploration dynamique pour connaˆ?tre la liste des méthodes disponibles (cf. paragraphe ??).
2.2.1 Listes
a = [1, 2, 3, 4, "maman", 5.1]
Les listes peuvent stocker, de manière ordonnée, des éléments de différents types.
Il est possible :
– d’accéder directement à un élément
| In [4]: r = [1, 2, 3, 7] In [5]: r[2] Out[5]: 3 In [6]: r[-1] Out[6]: 7 In [11]: r[-3] Out[11]: 2 |
En utilisant des indices négatifs, il est possible d’accéder aux éléments en partant de la fin (l’indice ?1 correspond au dernier élément, ?2 à l’avantdernier, )
– d’extraire des sous-listes :
| # tous les éléments renvoyés sont des listes In [4]: r Out[4]: [1, 2, 3, 7] In [7]: r[3:] Out[7]: [7] In [8]: r[2:] Out[8]: [3, 7] In [9]: r[:2] Out[9]: [1, 2] In [10]: r[::2] Out[10]: [1, 3] |
La syntaxe générale est : [indice début:indice fin:pas]. Ces paramètres sont facultatifs : par défaut, indice début correspond au premier indice de la liste (0), indice fin au dernier indice et pas à 1. En utilisant des pas négatifs, il est possible de parcourir la liste à l’envers. Par exemple a[::-1] permet d’inverser la liste (on parcours la liste du début à la fin avec un pas de ?1).
– d’ajouter des éléments à une liste
In [12]: a = [1, 2, 3]
In [13]: a.append(4)
In [14]: print a
[1, 2, 3, 4]
In [15]: b = [5, 6]
In [16]: a + b
Out[16]: [1, 2, 3, 4, 5, 6]
– de trier une liste
| In [2]: r = [2, 7, 1, 3] # la liste est en triée « en place » # => renvoie None In [3]: r.sort() # crée une nouvelle liste triée In [5]: a = sorted(r) In [4]: print r Out[4]: [1, 2, 3, 7] |
– de transformer une liste en chaˆ?ne de caractères :
In [7]: a = ["le", "petit", "chat"]
In [8]: "-".join(a)
Out[8]: ’le-petit-chat’
2.2.2 Des dictionnaires
Les dictionnaires permettent d’associer deux objets quelconques : le premier objet définit une clé; le suivant la valeur qui lui est associé.
In [29]: d = {’a’: 1, ’b’:1.2, ’c’:1j}
In [30]: d[’b’]
Out[30]: 1.2
In [31]: d[’d’] = ’d’
In [32]: d
Out[32]: {’a’: 1, ’b’: 1.2, ’c’: 1j, ’d’: ’d’}
In [33]: d.keys()
Out[33]: [’a’, ’c’, ’b’, ’d’]
In [34]: d.values()
Out[34]: [1, 1j, 1.2, ’d’]
2.2.3 Les chaˆ?nes de caractères
| a = ’Mine’ a = "Chris’s" # cha^?nes sur plusieurs lignes a = ’’’Mine and not his’’’ a = """Mine and Chris’s""" |
– les chaˆ?nes de caractères sont des listes :
| In [35]: s = ’Python is cool’ In [36]: s[-4:] Out[36]: ’cool’ |
– python fournit plusieurs méthodes intéressante :
In [1]: a = "Python is cool"
In [2]: a.replace("cool", "powerful")
Out[2]: ’Python is powerful’
In [3]: a.lower()
Out[3]: ’python is cool’
Nous verrons au paragraphe ?? comment découvrir facilement la liste complète des méthodes disponibles.
– substitution de chaˆ?ne de caractères
| In [38]: ’An integer: %i; a float: %f; another string: %s’ % (1, 0.1, ’string’ Out[38]: ’An integer: 1; a float: 0.100000; another string: string’ |
)
– construction d’une liste :
In [9]: "1;2;3;4".split(";")
Out[9]: [’1’, ’2’, ’3’, ’4’]
In [11]: "1 2 3 4".split()
Out[11]: [’1’, ’2’, ’3’, ’4’]
split(sep) retourne la liste des mots contenus dans une chaˆ?ne de caractères en supposant que ceux-ci sont séparés par sep. Si sep n’est pas fournit split considère que les mots sont séparés par un ou plusieurs espaces.
3 Structure de contrôle
3.1 Conditions
| In [23]: if a == 1: .: print 1 .: elif a == 2: .: print 2 .: else: .: print "beaucoup" .: .: beaucoup |
On remarquera que, en Python, les blocs sont délimités par l’indentation et seulement par l’indentation : il n’y a pas de begin/end ou d’accolades. Les conditions peuvent porter :
– soit sur des expressions booléennes
– soit sur des objets : un objet est vrai si sa valeur n’est pas nulle ou si sa longueur est strictement plus grande que 0 (pour les séquences) :
| In [1]: a = [] In [2]: if a: : print 1 : else: : print 2 : : 2 |
– il est également possible de tester si un objet appartient à une collection en utilisant le mot-clé in
| In [19]: a = [1, 2, 3, 5] In [20]: 2 in a Out[20]: True # pour les dictionnaires in teste l’existence d’une clé In [21]: b = {"name": "Guillaume", 2:3} In [22]: 2 in b Out[22]: True In [23]: "Guillaume" in b Out[23]: False # pour les string In [1]: a = "le chat et le chien" In [2]: "chien" in a Out[2]: True In [3]: "poisson" in a Out[3]: False |
3.2 Boucles
Pour itérer sur un index :
| In [24]: for i in range(4): .: print i .: .: 1 2 3 |
Cette boucle est équivalente au code C suivant :
| int i = 0; // for (i = 0; i < 4; i++) { printf("%d\n", i); } |
La fonction range permet de construire une liste d’entiers consécutifs : range(4) = [0, 1, 2, 3]. Il est possible d’itérer sur n’importe quelle séquence :
| In [25]: for word in [’cool’, ’powerful’, ’readable’]: .: print(’Python is %s’ % word) .: .: Python is cool |
Python is powerful
Python is readable
et même :
| In [26]: vowels = ’aeiouy’ In [27]: for i in ’powerful’: .: if i in vowels: .: print i, .: .: o e u |
La virgule à la fin du print permet d’éviter le retour chariot.
Python dispose également d’une boucle while
| In [28]: z = 1 + 1j In [29]: while abs(z) < 100: .: if z.imag == 0: .: break .: z = z ** 2 + 1 .: .: |
3.3 Utilisation avancée des boucles
La boucle for permet de parcourir les éléments d’un dictionnaire :
| In [7]: d = {’a’: 1, ’b’:1.2, ’c’:1j} In [8]: for key, val in d.iteritems(): : print(’Key: %s has value: %s’ % (key, val)) : : Key: a has value: 1 Key: c has value: 1j Key: b has value: 1.2 In [10]: for key in d: .: print key .: .: a c b |
Il est possible de construire directement des listes à l’aide de list comprehension :
In [4]: [i ** 2 for i in range(4)]
Out[4]: [0, 1, 4, 9]
In [5]: vowels = ’aeiouy’
In [6]: [i for i in "powerfull" if i in vowels] Out[6]: [’o’, ’e’, ’u’]
Pour parcourir une liste en conservant les indices des éléments, on peut utiliser le mot-clé enumerate :
| In [12]: word = "le chat" In [13]: for index, lettre in enumerate(word): .: print index, lettre .: .: 0 l 1 e 2 3 c 4 h 5 a 6 t |
4 Définir des fonctions
Une fonction est définie par le mot-clé def :
| In [1]: def area(radius): : return 3.14 * radius * radius : In [2]: area(1.5) Out[2]: 7.0649999999999995 |
Comme pour les structures de contrôles, le corps de la fonction est délimité par l’indentation. Une fonction peut, de manière optionnelle, renvoyer une valeur grâce au mot-clé return.
Au moment de l’appel, l’interpréteur s’assure que le nombres de paramètres de la fonction est correct :
| In [3]: def double_it(x): : return x * 2 : In [4]: double_it(3) Out[4]: 6 In [5]: double_it() --------------------------------------------------------------------------- TypeError Traceback (most recent call last) /people/wisniews/enseignement/enseignement2010/iri/cours/intro_python/< |
ipython console> in <module>()
TypeError: double_it() takes exactly 1 argument (0 given)
Il est également possible de définir des paramètres ayant des valeurs par défaut :
| In [6]: def double_it(x=2): : return x * 2 : In [7]: double_it(3) Out[7]: 6 In [8]: double_it() Out[8]: 4 |
On peut spécifier les paramètres en utilisant leur nom :
| In [9]: def slicer(seq, start=None, stop=None, step=None): : """Implement basic python slicing.""" : return seq[start:stop:step] : In [10]: seuss = ’one fish, two fish, red fish, blue fish’.split() In [11]: seuss Out[11]: [’one’, ’fish,’, ’two’, ’fish,’, ’red’, ’fish,’, ’blue’, ’fish’] In [12]: slicer(seuss) Out[12]: [’one’, ’fish,’, ’two’, ’fish,’, ’red’, ’fish,’, ’blue’, ’fish’] In [13]: slicer(seuss, step=2) Out[13]: [’one’, ’two’, ’red’, ’blue’] In [14]: slicer(seuss, 1, step=2) Out[14]: [’fish,’, ’fish,’, ’fish,’, ’fish’] In [15]: slicer(seuss, start=1, stop=4, step=2) Out[15]: [’fish,’, ’fish,’] |
Il est possible qu’une fonction retourne plusieurs valeurs :
| from __future__ import division def mean_var(lst): """ Calcule la moyenne et la variance d’une liste """ mean = sum(lst) / len(lst) var = sum([(x - mean) ** 2 for x in lst]) / len(lst) return mean, var m, v = mean_var(range(10)) |
Cette exemple montre plusieurs éléments intéressant de python : – la possibilité de retourner plusieurs valeurs dans une fonction;
– l’utilisation des fonctions sum et len;
– l’utilisation des docstring (la chaˆ?ne de caractères sous le nom de la fonction) pour documenter la fonction;
– l’utilisation du from __future__ import division pour que / corresponde à la division naturelle et non plus à la division entière.
Il est possible d’accéder à la docstring d’une fonction directement depuis l’interpréteur python grâce à la commande help
| In [18]: help(mean_var) Help on function mean_var in module __main__: mean_var(lst) Calcule la moyenne et la variance d’une liste |
5 Les objets
Voici un exemple d’objet en python
| class Basket: # attention: le premier argument doit toujours ^etre une référence # à l’objet, appelée, par convention, self def __init__(self, contents=None): if contents: self.contents = contents else: self.contents = [] def add(self, element): self.contents.append(element) def n_elements(self): """ Nombre d’éléments dans le panier """ return len(self.contents) def __str__(self): """ méthode qui est appelée par print (équivalent de toString en Java """ result = "" for element in self.contents: result = result + " " + element return "Contains: %s" % result def str_python(self): """ |
| Une manière plus dans l’esprit de python de coder __str__ """ return "contains: %s" % " ".join(self.contents) b = Basket() b.add("carottes") b.add("melon") print b # appel à __str__ |
1. toutes les méthodes de l’objet prennent obligatoirement, en premier argument une référence à l’objet (correspondant au this en Java ou en C++). Par convention, cet argument s’appelle toujours self.
2. la méthode correspondant au constructeur s’appelle __init__; pour créer un objet il suffit d’appeller le nom de l’objet en passant les paramètres (b = Basket())
3. il n’y a pas de mode d’accès en python (private, public en java); tous les attributs sont publics.
4. si b est une référence sur un objet, on peut accéder à ses attributs par b.nom_attribut et appeler ses méthodes par b.methode() (en fournis-
sant, si nécessaire, les paramètres)
6 Bibliothèque
6.1 Syntaxe
Il est possible d’utiliser des bibliothèques, après les avoirs importées par la commande from biblio import fonction1, fonction2. Certaines bibliothèques définissent de nouveaux objets qui peuvent être importés de la même manière. Python fournit de nombreuses bibliothèques de manière standard. On notera notamment :
– os qui contient des fonctions permettant de manipuler le système de fichier;
– re pour utiliser des expressions régulières;
– codec pour lire des fichiers contenant des accents;
– sys qui permet d’accéder au système et notamment aux entrées et sorties standards;
– pickle qui permet de sauvegarder (et de recharger) un objet dans un fichier. Il est possible de définir ses propres bibliothèques. Si l’on suppose que l’on dispose d’un fichier définissant une fonction build_from_directory et d’une classe Corpus, il est possible d’utiliser ceux-ci dans n’importe quel autre fichier python après avoir fait :
from corpus import Corpus, build_from_directory
Il faut toutefois que les deux fichiers soient dans le même répertoire.
6.2 Aide dynamique
Il est possible de connaˆ?tre le contenu d’un module de manière dynamique à l’aide des commandes dir et help :
| # les sorties des exemples suivants sont tronquées In [25]: import os In [26]: dir(os) Out[26]: [’fdopen’, ’fork’, ’forkpty’, ’fpathconf’, ’fstat’, ’fstatvfs’, ’fsync’, ’ftruncate’, ’getcwd’, ’getcwdu’, ’getegid’, ’getenv’, ’geteuid’, ’getgid’, ’getgroups’] In [27]: help(os) Help on module os: NAME os - OS routines for Mac, NT, or Posix depending on what system we are on. FILE MODULE DOCS DESCRIPTION This exports: - is one of the modules posixpath, or ntpath - is ’posix’, ’nt’, ’os2’, ’ce’ or ’riscos’ |
La commande dir permet d’accéder aux noms des fonctions et des objets contenus dans un module et des méthodes d’un objet; la commande dir permet d’obtenir l’aide correspondant à une variable, à une fonction, à un objet ou à un module. Cette aide est définie par les docstring.
In [28]: a = {}
In [29]: dir(a)
Out[29]:
[’clear’,
’copy’,
| ’fromkeys’, ’get’, ’has_key’, ’items’, ’iteritems’, ’iterkeys’, ’itervalues’, ’keys’, ’pop’, ’popitem’, ’setdefault’, ’update’, ’values’] #sortie tronquée In [30]: help(a.iterkeys) Help on built-in function iterkeys: iterkeys( ) D.iterkeys() -> an iterator over the keys of D (END) |
7 Utilisation de fichiers
L’ouverture et la fermeture d’un fichier se font par l’intermédiaire des commandes open et close :
In [67]: fp = open("", mode="r")
In [68]: fp
Out[68]: <open file ’’, mode ’r’ at 0xea1ec0>
In [73]: fp.close()
Un fichier peut être ouvert dans les modes suivant :
– lecture seul (mode="r")
– écriture seule (mode="w", si le fichier existe il est alors écrasé)
– ajout (mode="a")
Il est possible de lire un fichier ligne par ligne ou de lire toutes les lignes dans une liste en une seule opération :
| In [50]: fp = open("") In [69]: first_line = fp.readline() In [70]: first_line Out[70]: "GUARD: ’Allo, daffy English kaniggets and Monsieur Arthur-King, who is In [76]: all_lines = fp.readlines() In [77]: all_lines |
\n"
| Out[77]: ["GUARD: ’Allo, daffy English kaniggets and Monsieur Arthur-King, who is\n", ’ afraid of a duck, you know! So, we French fellows out-wit you a\n’, ’ second time!\n’, ’ \n’, ’ \n’] In [78]: all_lines[0] Out[78]: "GUARD: ’Allo, daffy English kaniggets and Monsieur Arthur-King, who is |
\n"
En utilisant une boucle for, il est possible d’itérer directement sur les lignes d’un fichier :
| In [81]: fp = open("") In [82]: for line in fp: .: print line .: GUARD: Allo, daffy English kaniggets and Monsieur Arthur-King, who is afraid of a duck, you know ! So, we French fellows out-wit you a second time ! |
La méthode write permet d’écrire dans un fichier :
In [83]: fp = open(’’, ’w’)
In [84]: fp.write("I am not a tiny-brained wiper of other people’s bottoms!")
In [85]: fp.close()
In [86]: fp = open(’’)
In [87]: ()
Out[87]: "I am not a tiny-brained wiper of other people’s bottoms!"
Il est possible de sauvegarder directement des objets Python dans un fichier grâce au module pickle.
| import pickle # exemple de sauvegarde d’objet data = {’a’: [1, 2.0, 3, 4+6j], ’b’: (’string’, u’Unicode string’), ’c’: None} output = open(’’, ’wb’) (data, output) output.close() |
| # pour recharger l’objet pkl_file = open(’’, ’rb’) data = (pkl_file) print data pkl_file.close() |
8 Correcteur orthographique en python
Nous allons maintenant illustrer les différents aspects de Python en étudiant un programme de correction orthographique complet. Le principe de ce correcteur est relativement simple : si l’on suppose que l’on dispose d’une liste de tous les mots avec leur fréquence d’apparition (un dictionnaire, il suffit, pour vérifier l’orthographe d’un mot de générer une liste de corrections possibles et choisir, parmi celles-ci, la plus fréquente.
Voici un programme python mettant en œuvre ce principe :
| import re, collections def words(text): return re.findall(’[a-z]+’, text.lower()) def train(features): model = collections.defaultdict(lambda: 1) for f in features: model[f] += 1 return model NWORDS = train(words(file(’’).read())) alphabet = ’abcdefghijklmnopqrstuvwxyz’ def edits1(word): s = [(word[:i], word[i:]) for i in range(len(word) + 1)] deletes = [a + b[1:] for a, b in s if b] transposes = [a + b[1] + b[0] + b[2:] for a, b in s if len(b) > 1] replaces = [a + c + b[1:] for a, b in s for c in alphabet if b] inserts = [a + c + b for a, b in s for c in alphabet] return set(deletes + transposes + replaces + inserts) def known(words): return set(w for w in words if w in NWORDS) def correct(word): candidates = known([word]) or known(edits1(word)) or [word] return max(candidates, ) |
– les fonctions words et train construisent le dictionnaire en i) segmentant un texte en mot et en ii) comptant le nombre d’occurrences de chaque mot;
– la fonction edits1 permet de générer une liste de corrections possibles en considérant :
– tous les mots obtenus en supprimant une des lettres du mot à corriger;
– tous les mots obtenus en échangeant deux lettres adjacentes;
– tous les mots obtenus en rempla¸cant une des lettres du mot à corriger;
– tous les mots obtenus en ajoutant une lettre au mot à corriger (à toutes les positions possibles);
Cette ensemble de correction n’est pas complet, mais il couvre la plupart des erreurs commises.
– la fonction known filtre les corrections possibles (générées par edits1 en ne gardant que celles qui sont dans le dictionnaire.
– la fonction correct parcourt la liste de toutes les corrections possibles et trouve la correction la plus fréquente, la première ligne de la fonction permet de sélectionner le premier ensemble qui n’est pas vide.
[1] Ces notes sont basées sur une présentation de Christopher Burns et Ga¨el Varoquaux à
Scipy’09
[2] L’encapsulation (qui n’est qu’une question de style!) est assurée par un mécanisme beaucoup plus puissant, les propriétés.
d’après http
