IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Introduction à Python 3 et au framework web Flask par l'exemple


précédentsommairesuivant

3. Les bases de Python

Image non disponible

3-1. Script [bases_01] : opérations élémentaires

Le script [bases_01] présente les premières caractéristiques de Python.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
# ----------------------------------
def affiche(chaine):
    # affiche chaine
    print("chaine=%s" % chaine)


# ----------------------------------
def affiche_type(variable):
    # affiche le type de variable
    print("type[%s]=%s" % (variable, type(variable)))


# ----------------------------------
def f1(param):
    # ajoute 10 à param
    return param + 10


# ----------------------------------
def f2():
    # rend un tuple de 3 valeurs
    return "un", 0, 100


# -------------------------------- programme principal ------------------------------------
# ceci est un commentaire
# variable utilisée sans avoir été déclarée
nom = "dupont"

# un affichage écran
print("nom=%s" % nom)

# une liste avec des éléments de type différent
liste = ["un", "deux", 3, 4]

# son nombre d'éléments
n = len(liste)

# une boucle
for i in range(n):
    print("liste[%d]=%s" % (i, liste[i]))

# initialisation de 2 variables avec un tuple
(chaine1, chaine2) = ("chaine1", "chaine2")

# concaténation des 2 chaînes
chaine3 = chaine1 + chaine2

# affichage résultat
print("[%s,%s,%s]" % (chaine1, chaine2, chaine3))

# utilisation fonction
affiche(chaine1)

# le type d'une variable peut être connu
affiche_type(n)
affiche_type(chaine1)
affiche_type(liste)

# le type d'une variable peut changer en cours d'exécution
n = "a changé"
affiche_type(n)

# une fonction peut rendre un résultat
res1 = f1(4)
print("res1=%s" % res1)

# une fonction peut rendre une liste de valeurs
(res1, res2, res3) = f2()
print("(res1,res2,res3)=[%s,%s,%s]" % (res1, res2, res3))

# on aurait pu récupérer ces valeurs dans une variable
liste = f2()
for i in range(len(liste)):
    print("liste[%s]=%s" % (i, liste[i]))

# des tests
for i in range(len(liste)):
    # n'affiche que les chaînes
    if type(liste[i]) == "str":
        print("liste[%s]=%s" % (i, liste[i]))

# d'autres tests
for i in range(len(liste)):
    # n'affiche que les entiers >10
    if type(liste[i]) == "int" and liste[i] > 10:
        print("liste[%s]=%s" % (i, liste[i]))

# une boucle while
liste = (8, 5, 0, -2, 3, 4)
i = 0
somme = 0
while i < len(liste) and liste[i] > 0:
    print("liste[%s]=%s" % (i, liste[i]))
    somme += liste[i]  # somme=somme+liste[i]
    i += 1  # i=i+1
print("somme=%s" % somme)
# fin programme

Commentaires 

  • ligne 2 : le mot clé def définit une fonction ;

  • ligne 2 : la fonction reçoit le paramètre [chaine]. On n'indique pas le type du paramètre. Python utilise exclusivement le passage par valeur. Celle-ci diffère selon la donnée :

    • pour un type simple (nombre, booléen…), cette valeur est la valeur encapsulée par la donnée (4, True…) ;

    • pour un type complexe (liste, classe…), cette valeur est l'adresse de la donnée ;

  • lignes 3-4 : le contenu de la fonction. Il est décalé à droite d'une tabulation. C'est cette indentation associée au caractère : de l'instruction def qui définit le contenu de la fonction. Cela est vrai pour toutes les instructions ayant du contenu : if, else, while, for, try, except ;

  • ligne 4 : la syntaxe utilisée ici est [print('text1%F1text2%F2…' % data1, data2)] :

    • les [%Fi] (ici %s) sont des formats d'affichage :

    • %s (string) : pour une chaîne de caractères ;

    • %d (decimal) : pour les nombres entiers décimaux signés ;

    • %f (float) : format décimal pour les nombres réels ;

    • %e (exponentiel) : format exponentiel pour un nombre réel ;

  • [data1, data2…] sont les expressions dont on veut afficher la valeur :

    • [data1] sera affichée avec le format F1 ;

    • [data2] sera affichée avec le format F2 ;

  • ligne 10 : Python gère en interne le type des variables. On peut connaître le type d'une variable avec la fonction type(variable) qui rend une variable de type 'type'. L'expression '%s' % (type(variable)) est une chaîne de caractères représentant le type de la variable ;

  • ligne 25 : le programme principal. Celui-ci vient habituellement (mais pas nécessairement) après la définition de toutes les fonctions du script. Son contenu est non indenté ;

  • ligne 28 : en Python, on ne déclare pas les variables. Python est sensible à la casse. La variable Nom est différente de la variable nom. Une chaîne de caractères peut être entourée de guillemets " ou d'apostrophes '. On peut donc écrire 'dupont' ou "dupont" ;

  • ligne 34 : il y a une différence entre un tuple (1,2,3) (notez les parenthèses) et une liste [1,2,3] (notez les crochets). Le tuple est non modifiable alors que la liste l'est. Dans les deux cas, l'élement n° i est noté [i] ;

  • ligne 40 : range(n) est le tuple (0,1,2,…,n-1) ;

  • ligne 41 : le format %d est utilisé pour les nombres entiers signés ;

  • ligne 74 : len(var) est le nombre d'éléments de la collection var (tuple, liste, dictionnaire…) ;

  • ligne 84 : la structure [for in …] permet d'itérer une structure itérable. Les listes et les tuples sont des éléments itérables ;

  • ligne 86 : les autres opérateurs booléens sont or et not ;

  • ligne 93 : fait la somme des nombres >0 de la liste ;

Les résultats écran sont les suivants :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_01.py
nom=dupont
liste[0]=un
liste[1]=deux
liste[2]=3
liste[3]=4
[chaine1,chaine2,chaine1chaine2]
chaine=chaine1
type[4]=<class 'int'>
type[chaine1]=<class 'str'>
type[['un', 'deux', 3, 4]]=<class 'list'>
type[a changé]=<class 'str'>
res1=14
(res1,res2,res3)=[un,0,100]
liste[0]=un
liste[1]=0
liste[2]=100
liste[0]=8
liste[1]=5
somme=13

Process finished with exit code 0

3-2. Script [bases_02]  : chaînes de formatage

Python 3 a amené une nouvelle façon de formater les chaînes de caractères :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
# chaînes de formatage
# les formats sont ceux du langage C
# entier
int1 = 10
print(f"[int1={int1}]")
print(f"[int1={int1:4d}]")
print(f"[int1={int1:04d}]")
# float
float1=8.2
print(f"[float1={float1}]")
print(f"[float1={float1:8.2f}]")
print(f"[float1={float1:.3e}]")
# string
str1="abcd"
print(f"[str1={str1}]")
print(f"[str1={str1:8s}]")
str2="jean de florette"
print(f"[{str2:20.10s}]")
# les chaînes formatées peuvent être affectées à des variables
str3=f"[{str2:20.10s}]"
print(str3)

La syntaxe de la chaîne formatée est la suivante :

 
Sélectionnez
1.
f'…{expr1:format1} …. {expr2:format2} ….'

avec :

  • [expri] : une expression ;

  • [formati] : le format de l'expression [expri]. Ces formats sont ceux du langage C :

  • %d : pour les nombres entiers ;

  • %f : notation décimale pour les nombres réels ;

  • %e : notation exponentielle pour les nombres réels ;

  • %s : pour les chaînes de caractères. C'est le format utilisé lorsqu'aucun format n'est utilisé pour [expri] ;

  • %nd, %nf, %ns : affiche [expri] sur n caractères : la chaîne est soit tronquée, soit complétée avec des espaces;

  • ligne 7 : [04d], entier sur 4 caractères complétés à gauche avec des zéros;

  • ligne 11 : [8.2f], réel décimal sur 8 caractères dont 2 après la virgule ;

  • ligne 12 : [.3e], réel sous forme exponentielle avec 3 décimales pour la mantisse ;

  • ligne 18 : [20.10s], les 10 premiers caractères d'une chaîne complétée avec des espaces pour faire 20 caractères ;

Les résultats de l'exécution sont les suivants :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_02.py
[int1=10]
[int1=  10]
[int1=0010]
[float1=8.2]
[float1=    8.20]
[float1=8.200e+00]
[str1=abcd]
[str1=abcd    ]
[jean de fl          ]
[jean de fl          ]

Process finished with exit code 0

3-3. Script [bases_03] : changements de types

On s'intéresse ici aux changements de types avec des données de type str (chaîne de caractères), int (entier), float (réel), bool (booléen).

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
# changements de type
# int --> str, float, bool
x = 4
print(x, type(x))
x = str(4)
print(x, type(x))
x = float(4)
print(x, type(x))
x = bool(4)
print(x, type(x))

# bool --> int, float, str
x = True
print(x, type(x))
x = int(True)
print(x, type(x))
x = float(True)
print(x, type(x))
x = str(True)
print(x, type(x))

# str --> int, float, bool
x = "4"
print(x, type(x))
x = int("4")
print(x, type(x))
x = float("4")
print(x, type(x))
x = bool("4")
print(x, type(x))

# float --> str, int, bool
x = 4.32
print(x, type(x))
x = str(4.32)
print(x, type(x))
x = int(4.32)
print(x, type(x))
x = bool(4.32)
print(x, type(x))

# gestion des erreurs de changement de type
try:
    x = int("abc")
    print(x, type(x))
except ValueError as erreur:
    print(erreur)

# cas divers
x = bool("abc")
print(x, type(x))
x = bool("")
print(x, type(x))
x = bool(0)
print(x, type(x))
x = None
print(x, type(x))
x = bool(None)
print(x, type(x))
x = bool(0.0)
print(x, type(x))

# toutes les données sont des instances de classe et à ce titre ont des méthodes
# chaîne de caractères
str1 = "abc"
print(str1.capitalize())
# nombre entier
int1 = 4
print(int1.bit_length())
# booléen
bool1=True
print(bool1.conjugate())
# nombre réel
float1=8.2
print (float1.is_integer())

De nombreux changements de type sont possibles. Certains peuvent échouer, comme celui des lignes 46-47 qui essaient de transformer la chaîne 'abc' en nombre entier. On a géré l'erreur avec une structure try / except. Une forme générale de cette structure est la suivante :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
try:
	actions
except Exception as ex:
	actions
finally:
	actions

Si l'une des actions du try lance une exception (signale une erreur), il y a branchement immédiat sur la clause except. Si les actions du try ne lancent pas d'exception, la clause except est ignorée. Les attributs Exception et ex de l'instruction except sont facultatifs. Lorsqu'ils sont présents, Exception précise le type d'exception interceptée par l'instruction except et ex contient l’exception qui s’est produite. Il peut y avoir plusieurs instructions except, si on veut gérer différents types d'exceptions dans le même try.

L'instruction finally est facultative. Si elle est présente, les actions du finally sont toujours exécutées qu'il y ait eu exception ou non.

Nous reviendrons sur les exceptions un peu plus loin.

Les lignes 49-61 montrent diverses tentatives pour transformer une donnée de type str, int, float, NoneType en booléen. C'est toujours possible. Les règles sont les suivantes :

  • bool(int i) vaut False si i vaut 0, True dans tous les autres cas ;

  • bool(float f) vaut False si f vaut 0.0, True dans tous les autres cas ;

  • bool(str chaine) vaut False si chaine a 0 caractère, True dans tous les autres cas ;

  • bool(None) vaut False. None est une valeur spéciale qui signifie que la variable existe mais n'a pas de valeur.

Les résultats écran sont les suivants :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_03.py
4 <class 'int'>
4 <class 'str'>
4.0 <class 'float'>
True <class 'bool'>
True <class 'bool'>
1 <class 'int'>
1.0 <class 'float'>
True <class 'str'>
4 <class 'str'>
4 <class 'int'>
4.0 <class 'float'>
True <class 'bool'>
4.32 <class 'float'>
4.32 <class 'str'>
4 <class 'int'>
True <class 'bool'>
invalid literal for int() with base 10: 'abc'
True <class 'bool'>
False <class 'bool'>
False <class 'bool'>
None <class 'NoneType'>
False <class 'bool'>
False <class 'bool'>
Abc
3
1
False

Process finished with exit code 0

On notera que toutes les données sont des objets, c'est-à-dire des instances de classe. Cela signifie qu'elles peuvent avoir des méthodes. C'est ce que montrent les lignes 63-75 du code. Nous ne cherchons pas ici à expliquer ce que font les méthodes utilisées mais simplement à montrer qu'elles existent.

3-4. Script [bases_04]: portée des variables

Le script [bases_04] montre que Python n'a pas la notion de variable de portée bloc :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
# portée des variables
i = 4
if True:
    i += 1
    j = 7
print(f"i={i}, j={j}")

Résultats

 
Sélectionnez
1.
2.
3.
4.
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_04.py
i=5, j=7

Process finished with exit code 0

Commentaires

Les résultats montrent deux choses :

  • ligne 4 : la variable [i] du bloc [if] est la même que la variable i utilisée ligne 2 ;

  • ligne 6 : la variable [j] est celle initialisée dans le bloc [if] ;

Dans certains langages, où on déclare les variables, une variable définie dans un bloc (comme celui des lignes 3-5) n'est pas connue à l'extérieur de celui-ci. En Python, rien de tel.

3-5. Script [bases_05] : listes - 1

Le script [bases_05] est le suivant :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
# listes à 1 dimension
# initialisation
list1 = [0, 1, 2, 3, 4, 5]

# parcours - 1
print(f"list1 a {len(list1)} éléments")
for i in range(len(list1)):
    print(f"list1[{i}]={list1[i]}")

list1[1] = 10
# parcours - 2
print(f"list1 a {len(list1)} éléments")
for element in list1:
    print(element)

# ajout de deux éléments
list1[len(list1):] = [10, 11]
# le format %s permet d'afficher la liste sur une ligne
print("%s" % list1)

# suppression des deux derniers éléments
list1[len(list1) - 2:] = []
# le format par défaut permet d'afficher la liste sur une ligne
print(f"{list1}")

# ajout en début de liste d'une liste
list1[:0] = [-10, -11, -12]
print(f"{list1}")

# insertion en milieu de liste de deux éléments
list1[3:3] = [100, 101]
print(f"{list1}")

# suppression de deux éléments en milieu de liste
list1[3:4] = []
print(f"{list1}")

Notes :

  • la notation tableau[i:j] désigne les éléments i à j-1 du tableau ;

  • la notation [i:] désigne les éléments i et suivants du tableau ;

  • la notation [:i] désigne les éléments 0 à i-1 du tableau ;

  • ligne 19 : print (%s) % (list1) affiche la chaîne de caractères : "[ list1[0], list1[2]…, list1[n-1]]" ;

  • ligne 24 : la notation print ('f{list1}') fait la même chose ;

Résultats

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_05.py
list1 a 6 éléments
list1[0]=0
list1[1]=1
list1[2]=2
list1[3]=3
list1[4]=4
list1[5]=5
list1 a 6 éléments
0
10
2
3
4
5
[0, 10, 2, 3, 4, 5, 10, 11]
[0, 10, 2, 3, 4, 5]
[-10, -11, -12, 0, 10, 2, 3, 4, 5]
[-10, -11, -12, 100, 101, 0, 10, 2, 3, 4, 5]
[-10, -11, -12, 101, 0, 10, 2, 3, 4, 5]

Process finished with exit code 0

3-6. Script [bases_06] : listes - 2

Le code précédent peut être écrit différemment (bases_06) en utilisant certaines méthodes des listes :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
# listes à 1 dimension

# initialisation
list1 = [0, 1, 2, 3, 4, 5]

# parcours - 1
print(f"list1 a {len(list1)} éléments")
for i in range(len(list1)):
    print(f"list1[{i}]={list1[i]}")

# modification d'un élément
list1[1] = 10

# parcours - 2
print(f"list1 a {len(list1)} éléments")
for element in list1:
    print(element)

# ajout de deux éléments
list1.extend([10, 11])
print(f"{list1}")

# suppression des deux derniers éléments
del list1[len(list1) - 2:]
print(f"{list1}")

# ajout en début de liste d'un tuple
for i in (-12, -11, -10):
    list1.insert(0, i)
print(f"{list1}")

# insertion en milieu de liste
for i in (101, 100):
    list1.insert(3, i)
print(f"{list1}")

# suppression en milieu de liste
del list1[3:4]
print(f"{list1}")

Les résultats obtenus sont les mêmes qu'avec la version précédente.

3-7. script [bases_07] : le dictionnaire

Le script [bases_07] montre comment définir et exploiter un dictionnaire, parfois appelé tableau associatif.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
# une fonction qui vérifie si la clé mari existe dans le dictionnaire conjoints
def existe(conjoints, mari):
    if mari in conjoints:
        print(f"La clé [{mari}] existe associée à la valeur [{conjoints[mari]}]")
    else:
        print(f"La clé [{mari}] n'existe pas")


# ----------------------------- Main
# un dictionnaire
conjoints = {"Pierre": "Gisèle", "Paul": "Virginie", "Jacques": "Lucette", "Jean": ""}

# parcours - 1
print(f"Nombre d'éléments du dictionnaire : {len(conjoints)}")
for (clé, valeur) in conjoints.items():
    print(f"conjoints[{clé}]={valeur}")

# liste des clés du dictionnaire
print("liste des clés-------------")
clés = conjoints.keys()
print(f"{clés}")

# liste des valeurs du dictionnaire
print("liste des valeurs------------")
valeurs = conjoints.values()
print(f"{valeurs}")

# recherche d'une clé
existe(conjoints, "Jacques")
existe(conjoints, "Lucette")
existe(conjoints, "Jean")

# suppression d'une clé-valeur
del (conjoints["Jean"])
print(f"Nombre d'éléments du dictionnaire : {len(conjoints)}")
print(f"{conjoints}")

# les clés et valeurs d'un dictionnaire ne sont pas des listes
print(f"type des clés : {type(clés)}")
print(f"type des valeurs : {type(valeurs)}")

# on peut les transformer en listes
lclés = list(clés)
print(f"clés : {type(lclés)}, {lclés}")
lvaleurs = list(valeurs)
print(f"valeurs : {type(lvaleurs)}, {lvaleurs}")

Notes :

  • ligne 11 : la définition en dur d'un dictionnaire ;

  • ligne 15 : conjoints.items() rend la liste des couples (clé,valeur) du dictionnaire conjoints ;

  • ligne 20 : conjoints.keys() rend les clés du dictionnaire conjoints ;

  • ligne 25 : conjoints.values() rend les valeurs du dictionnaire conjoints ;

  • ligne 3 : mari in conjoints rend True si la clé mari existe dans le dictionnaire conjoints, False sinon ;

  • ligne 36 : un dictionnaire peut être affiché en une seule ligne.

Résultats

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_07.py
Nombre d'éléments du dictionnaire : 4
conjoints[Pierre]=Gisèle
conjoints[Paul]=Virginie
conjoints[Jacques]=Lucette
conjoints[Jean]=
liste des clés-------------
dict_keys(['Pierre', 'Paul', 'Jacques', 'Jean'])
liste des valeurs------------
dict_values(['Gisèle', 'Virginie', 'Lucette', ''])
La clé [Jacques] existe associée à la valeur [Lucette]
La clé [Lucette] n'existe pas
La clé [Jean] existe associée à la valeur []
Nombre d'éléments du dictionnaire : 3
{'Pierre': 'Gisèle', 'Paul': 'Virginie', 'Jacques': 'Lucette'}
type des clés : <class 'dict_keys'>
type des valeurs : <class 'dict_values'>
clés : <class 'list'>, ['Pierre', 'Paul', 'Jacques']
valeurs : <class 'list'>, ['Gisèle', 'Virginie', 'Lucette']

Process finished with exit code 0

Notes :

  • on notera aux lignes 16-17 des résultats que les clés et valeurs d'un dictionnaire ne forment pas une liste mais un type 'dict_keys' ;

  • lignes 18-19 : un simple changement de type permet de les convertir en un type [list] ;

3-8. script [bases_08] : les tuples

Le tuple a des similitudes avec la liste mais est non modifiable :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
# tuples
# initialisation
tuple1 = (0, 1, 2, 3, 4, 5)

# parcours - 1
print(f"tuple1 a {len(tuple1)} elements")
for i in range(len(tuple1)):
    print(f"tuple1[{i}]={tuple1[i]}")

# parcours - 2
print(f"tuple1 a {len(tuple1)} elements")
for element in tuple1:
    print(element)

# un tuble peut être affiché en une ligne
print(f"tuple1={tuple1}")

# un tuple ne peut être modifié
tuple1[0] = 10

Résultats

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_08.py
tuple1 a 6 elements
tuple1[0]=0
tuple1[1]=1
tuple1[2]=2
tuple1[3]=3
tuple1[4]=4
tuple1[5]=5
tuple1 a 6 elements
0
1
2
3
4
5
tuple1=(0, 1, 2, 3, 4, 5)
Traceback (most recent call last):
  File "C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_08.py", line 19, in <module>
    tuple1[0] = 10
TypeError: 'tuple' object does not support item assignment

Process finished with exit code 1

Notes :

  • lignes 17-20 des résultats : montrent qu'un tuple ne peut pas être modifié.

3-9. Script [bases_09] : les listes et dictionnaires à plusieurs dimensions

Le script [bases_09] montre comment définir et exploiter une liste ou un dictionnaire multidimensionnel :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
# listes multidimensionnelles
# initialisation
multi = [[0, 1, 2], [10, 11, 12, 13], [20, 21, 22, 23, 24]]

# parcours
for i1 in range(len(multi)):
    for i2 in range(len(multi[i1])):
        print(f"multi[{i1}][{i2}]={multi[i1][i2]}")

# affichage en une ligne
print(f"multi={multi}")

# dictionnaires multidimensionnels
# initialisation
multi = {"zéro": [0, 1], "un": [10, 11, 12, 13], "deux": [20, 21, 22, 23, 24]}

# parcours
for (clé, valeur) in multi.items():
    for i2 in range(len(valeur)):
        print(f"multi[{clé}][{i2}]={multi[clé][i2]}")

# affichage en une ligne
print(f"multi={multi}")

Commentaires

  • ligne 7 : multi[i1] est une liste ;

  • ligne 18 : valeur est une liste ;

Résultats

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_09.py
multi[0][0]=0
multi[0][1]=1
multi[0][2]=2
multi[1][0]=10
multi[1][1]=11
multi[1][2]=12
multi[1][3]=13
multi[2][0]=20
multi[2][1]=21
multi[2][2]=22
multi[2][3]=23
multi[2][4]=24
multi=[[0, 1, 2], [10, 11, 12, 13], [20, 21, 22, 23, 24]]
multi[zéro][0]=0
multi[zéro][1]=1
multi[un][0]=10
multi[un][1]=11
multi[un][2]=12
multi[un][3]=13
multi[deux][0]=20
multi[deux][1]=21
multi[deux][2]=22
multi[deux][3]=23
multi[deux][4]=24
multi={'zéro': [0, 1], 'un': [10, 11, 12, 13], 'deux': [20, 21, 22, 23, 24]}

Process finished with exit code 0

3-10. Script [bases_10] : liens entre chaînes et listes

Le script [bases_10] montrent comment récupérer dans une liste les éléments d'une chaîne séparés par un même séparateur.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
# chaîne vers liste
chaine = '1:2:3:4'
liste = chaine.split(':')
print(type(liste))

# affichage liste
print(f"liste a {len(liste)} éléments")
print(f"liste={liste}")

# liste vers chaîne
chaine2 = ":".join(liste)
print(f"chaine2={chaine2}")

# ajoutons un champ vide
chaine += ":"
print(f"chaine={chaine}")
liste = chaine.split(":")

# affichage liste
print(f"liste a {len(liste)} éléments")
print(f"liste={liste}")

# ajoutons de nouveau un champ vide
chaine += ":"
print(f"chaine={chaine}")
liste = chaine.split(":")

# affichage liste
print(f"liste a {len(liste)} éléments")
print(f"liste={liste}")

Notes :

  • ligne 3 : la méthode chaine.split(séparateur) découpe la chaîne de caractères chaine en éléments séparés par séparateur et les rend sous forme de liste. Ainsi l'expression '1:2:3:4'.split(":") a pour valeur la liste ('1','2','3','4') ;

  • ligne 11 : 'separateur'.join(liste) a pour valeur la chaîne de caractères 'liste[0]+separateur+liste[1]+separateur+…'.

Résultats

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_10.py
<class 'list'>
liste a 4 éléments
liste=['1', '2', '3', '4']
chaine2=1:2:3:4
chaine=1:2:3:4:
liste a 5 éléments
liste=['1', '2', '3', '4', '']
chaine=1:2:3:4::
liste a 6 éléments
liste=['1', '2', '3', '4', '', '']

Process finished with exit code 0

3-11. Script [bases_11] : les expressions régulières

Le script [bases_11] montre comment utiliser des expressions régulières :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
# on importe le module des expressions régulières
import re


# --------------------------------------------------------------------------
def compare(modèle, chaine):
    # compare la chaîne [chaîne] au modèle [modèle]
    # affichage résultats
    print(f"\nRésultats({chaine},{modèle})")
    match = re.match(modèle, chaine)
    if match:
        print(match.groups())
    else:
        print(f"La chaîne [{chaine}] ne correspond pas au modèle [{modèle}]")


# expression régulières en python
# récupérer les différents champs d'une chaîne
# le modèle : une suite de chiffres entourée de caractères quelconques
# on ne veut récupérer que la suite de chiffres
modèle = r"^.*?(\d+).*?$"

# on confronte la chaîne au modèle
compare(modèle, "xyz1234abcd")
compare(modèle, "12 34")
compare(modèle, "abcd")

# le modèle : une suite de chiffres entourée de caractères quelconques
# on veut la suite de chiffres ainsi que les champs qui suivent et précèdent
modèle = r"^(.*?)(\d+)(.*?)$"

# on confronte la chaîne au modèle
compare(modèle, "xyz1234abcd")
compare(modèle, "12 34")
compare(modèle, "abcd")

# le modèle - une date au format jj/mm/aa
modèle = r"^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$"
compare(modèle, "10/05/97")
compare(modèle, " 04/04/01 ")
compare(modèle, "5/1/01")

# le modèle - un nombre décimal
modèle = r"^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$"
compare(modèle, "187.8")
compare(modèle, "-0.6")
compare(modèle, "4")
compare(modèle, ".6")
compare(modèle, "4.")
compare(modèle, " + 4")
# fin

Notes :

  • noter le module [re] importé en ligne 2. C'est lui qui contient les fonctions de gestion des expressions régulières ;

  • ligne 10 : la comparaison d'une chaîne à une expression régulière (modèle) rend le booléen True si la chaîne correspond au modèle, False sinon ;

  • ligne 12 : match.groups() est un tuple dont les éléments sont les parties de la chaîne qui correspondent aux éléments de l'expression régulière entourés de parenthèses. Dans le modèle :

  • ^.*?(\d+).*?, match.groups() sera un tuple d'un élément parce qu'il y a une parenthèse ;

  • ^(.*?)(\d+)(.*?)$, match.groups() sera un tuple de 3 éléments parce qu'il y a trois parenthèses ;

  • ligne 21 : une expression régulière littérale est notée r"xxx". C'est le symbole r qui fait de la chaîne une expression régulière ;

Les expressions régulières nous permettent de tester le format d'une chaîne de caractères. Ainsi on peut vérifier qu'une chaîne représentant une date est au format jj/mm/aa. On utilise pour cela un modèle et on compare la chaîne à ce modèle. Ainsi dans cet exemple, j m et a doivent être des chiffres. Le modèle d'un format de date valide est alors "\d\d/\d\d/\d\d" où le symbole \d désigne un chiffre. Les symboles utilisables dans un modèle sont les suivants :

Caractère

Description

\

Marque le caractère suivant comme caractère spécial ou littéral. Par exemple, "n" correspond au caractère "n" alors que "\n" correspond à un caractère de nouvelle ligne. La séquence "\\" correspond à "\", tandis que "\(" correspond à "(".

^

Correspond au début de la chaîne.

$

Correspond à la fin de la chaîne.

*

Correspond au caractère précédent, zéro fois ou plusieurs fois. Ainsi, "zo*" correspond à "z" ou à "zoo".

+

Correspond au caractère précédent, une ou plusieurs fois. Ainsi, "zo+" correspond à "zoo", mais pas à "z".

?

Correspond au caractère précédent, zéro ou une fois. Par exemple, "a?ve?" correspond à "ve" dans "lever".

.

Correspond à tout caractère unique, sauf le caractère de nouvelle ligne.

(modèle)

Recherche le modèle et mémorise la correspondance. La sous-chaîne correspondante peut être extraite de la collection match.groups(). Pour trouver des correspondances avec des caractères entre parenthèses ( ), utilisez "\(" ou "\)".

x|y

Correspond soit à x soit à y. Par exemple, "z|foot" correspond à "z" ou à "foot". "(z|f)oo" correspond à "zoo" ou à "foo".

{n}

n est un nombre entier non négatif. Correspond exactement à n fois le caractère. Par exemple, "o{2}" ne correspond pas à "o" dans "Bob," mais aux deux premiers "o" dans "fooooot".

{n,}

n est un entier non négatif. Correspond à au moins n fois le caractère. Par exemple, "o{2,}" ne correspond pas à "o" dans "Bob", mais à tous les "o" dans "fooooot". "o{1,}" équivaut à "o+" et "o{0,}" équivaut à "o*".

{ n , m }

m et n sont des entiers non négatifs. Correspond à au moins n et à au plus m fois le caractère. Par exemple, "o{1,3}" correspond aux trois premiers "o" dans "foooooot" et "o{0,1}" équivaut à "o?".

[xyz]

Jeu de caractères. Correspond à l'un des caractères indiqués. Par exemple, "[abc]" correspond à "a" dans "plat".

[^xyz]

Jeu de caractères négatif. Correspond à tout caractère non indiqué. Par exemple, "[^abc]" correspond à "p" dans "plat".

[a-z]

Plage de caractères. Correspond à tout caractère dans la série spécifiée. Par exemple, "[a-z]" correspond à tout caractère alphabétique minuscule compris entre "a" et "z".

[^m-z]

Plage de caractères négative. Correspond à tout caractère ne se trouvant pas dans la série spécifiée. Par exemple, "[^m-z]" correspond à tout caractère ne se trouvant pas entre "m" et "z".

\b

Correspond à une limite représentant un mot, autrement dit, à la position entre un mot et un espace. Par exemple, "er\b" correspond à "er" dans "lever", mais pas à "er" dans "verbe".

\B

Correspond à une limite ne représentant pas un mot. "en*t\B" correspond à "ent" dans "bien entendu".

\d

Correspond à un caractère représentant un chiffre. Équivaut à [0-9].

\D

Correspond à un caractère ne représentant pas un chiffre. Équivaut à [^0-9].

\f

Correspond à un caractère de saut de page.

\n

Correspond à un caractère de nouvelle ligne.

\r

Correspond à un caractère de retour chariot.

\s

Correspond à tout espace blanc, y compris l'espace, la tabulation, le saut de page, etc. Équivaut à "[ \f\n\r\t\v]".

\S

Correspond à tout caractère d'espace non blanc. Équivaut à "[^ \f\n\r\t\v]".

\t

Correspond à un caractère de tabulation.

\v

Correspond à un caractère de tabulation verticale.

\w

Correspond à tout caractère représentant un mot et incluant un trait de soulignement. Équivaut à "[A-Za-z0-9_]".

\W

Correspond à tout caractère ne représentant pas un mot. Équivaut à "[^A-Za-z0-9_]".

\num

Correspond à num, où num est un entier positif. Fait référence aux correspondances mémorisées. Par exemple, "(.)\1" correspond à deux caractères identiques consécutifs.

\ n

Correspond à n, où n est une valeur d'échappement octale. Les valeurs d'échappement octales doivent comprendre 1, 2 ou 3 chiffres. Par exemple, "\11" et "\011" correspondent tous les deux à un caractère de tabulation. "\0011" équivaut à "\001" & "1". Les valeurs d'échappement octales ne doivent pas excéder 256. Si c'était le cas, seuls les deux premiers chiffres seraient pris en compte dans l'expression. Permet d'utiliser les codes ASCII dans des expressions régulières.

\xn

Correspond à n, où n est une valeur d'échappement hexadécimale. Les valeurs d'échappement hexadécimales doivent comprendre deux chiffres obligatoirement. Par exemple, "\x41" correspond à "A". "\x041" équivaut à "\x04" & "1". Permet d'utiliser les codes ASCII dans des expressions régulières.

Un élément dans un modèle peut être présent en 1 ou plusieurs exemplaires. Considérons quelques exemples autour du symbole \d qui représente 1 chiffre :

modèle

signification

\d

un chiffre

\d?

0 ou 1 chiffre

\d*

0 ou davantage de chiffres

\d+

1 ou davantage de chiffres

\d{2}

2 chiffres

\d{3,}

au moins 3 chiffres

\d{5,7}

entre 5 et 7 chiffres

Imaginons maintenant le modèle capable de décrire le format attendu pour une chaîne de caractères :

chaîne recherchée

modèle

une date au format jj/mm/aa

\d{2}/\d{2}/\d{2}

une heure au format hh:mm:ss

\d{2}:\d{2}:\d{2}

un nombre entier non signé

\d+

un suite d'espaces éventuellement vide

\s*

un nombre entier non signé qui peut être précédé ou suivi d'espaces

\s*\d+\s*

un nombre entier qui peut être signé et précédé ou suivi d'espaces

\s*[+|-]?\s*\d+\s*

un nombre réel non signé qui peut être précédé ou suivi d'espaces

\s*\d+(.\d*)?\s*

un nombre réel qui peut être signé et précédé ou suivi d'espaces

\s*[+-]?\s*\d+(.\d*)?\s*

une chaîne contenant le mot juste

\bjuste\b

On peut préciser où on recherche le modèle dans la chaîne :

modèle

signification

^modèle

le modèle commence la chaîne

modèle$

le modèle finit la chaîne

^modèle$

le modèle commence et finit la chaîne

modèle

le modèle est cherché partout dans la chaîne en commençant par le début de celle-ci.

chaîne recherchée

modèle

une chaîne se terminant par un point d'exclamation

!$

une chaîne se terminant par un point

\.$

une chaîne commençant par la séquence //

^//

une chaîne ne comportant qu'un mot éventuellement suivi ou précédé d'espaces

^\s*\w+\s*$

une chaîne ne comportant deux mot éventuellement suivis ou précédés d'espaces

^\s*\w+\s*\w+\s*$

une chaîne contenant le mot secret

\bsecret\b

Les sous-ensembles d'un modèle peuvent être "récupérés". Ainsi non seulement, on peut vérifier qu'une chaîne correspond à un modèle particulier mais on peut récupérer dans cette chaîne les éléments correspondant aux sous-ensembles du modèle qui ont été entourés de parenthèses. Ainsi si on analyse une chaîne contenant une date jj/mm/aa et si on veut de plus récupérer les éléments jj, mm, aa de cette date on utilisera le modèle (\d\d)/(\d\d)/(\d\d).

Résultats du script

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_11.py

Résultats(xyz1234abcd,^.*?(\d+).*?$)
('1234',)

Résultats(12 34,^.*?(\d+).*?$)
('12',)

Résultats(abcd,^.*?(\d+).*?$)
La chaîne [abcd] ne correspond pas au modèle [^.*?(\d+).*?$]

Résultats(xyz1234abcd,^(.*?)(\d+)(.*?)$)
('xyz', '1234', 'abcd')

Résultats(12 34,^(.*?)(\d+)(.*?)$)
('', '12', ' 34')

Résultats(abcd,^(.*?)(\d+)(.*?)$)
La chaîne [abcd] ne correspond pas au modèle [^(.*?)(\d+)(.*?)$]

Résultats(10/05/97,^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$)
('10', '05', '97')

Résultats( 04/04/01 ,^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$)
('04', '04', '01')

Résultats(5/1/01,^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$)
La chaîne [5/1/01] ne correspond pas au modèle [^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$]

Résultats(187.8,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('', '187.8')

Résultats(-0.6,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('-', '0.6')

Résultats(4,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('', '4')

Résultats(.6,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('', '.6')

Résultats(4.,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('', '4.')

Résultats( + 4,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('+', '4')

Process finished with exit code 0

précédentsommairesuivant

Licence Creative Commons
Le contenu de cet article est rédigé par Serge Tahé et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 3.0 non transposé.
Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright © 2020 Developpez.com.