IV. Chapitre 3▲
« Notre imagination est mise à rude épreuve, non pas, comme dans la fiction, pour imaginer des choses qui n’existent pas vraiment, mais juste pour comprendre ce qui est là. »
Richard Feymann
IV-A. Plongée dans Python▲
Tout langage de programmation a cette fonctionnalité caractéristique, une chose complexe rendue simple intentionnellement. Si vous venez d'un autre langage, vous pouvez passer à côté, car votre précédent langage n'a pas rendu la même chose facile (celui-ci étant occupé à simplifier autre chose). Ce chapitre va vous enseigner les compréhensions de listes (NDT : aussi appelées listes en compréhensions ou listes en intentions), les compréhensions de dictionnaires, ainsi que les compréhensions de sets : trois concepts intimement centrés autour d'une seule puissante technique. Mais pour commencer, je voudrais faire un petit détour par deux modules qui vous aideront à naviguer dans votre système de fichier local.
IV-B. Travailler avec des fichiers et répertoires▲
Python 3 est fourni avec un module nommé os, pour « operating system » (système d'exploitation). Le module os contient une pléthore de fonctions afin de récupérer des informations relatives au système et dans certains cas, pour manipuler des répertoires locaux, fichiers, processus et variables d'environnement. Python fait de son mieux pour offrir une API unifiée supportant tous les systèmes d'exploitation afin que votre programme fonctionne sur n'importe quel ordinateur avec le moins de code spécifique à votre système que possible. Vous pouvez télécharger cette API ici :
IV-B-1. Le répertoire courant▲
Lorsque vous débutez avec Python, vous allez passer beaucoup de temps avec le Shell Python. Tout au long de ce livre, vous verrez des exemples sous cette forme :
- importez un des modules Python;
- appelez une fonction de ce module ;
- expliquez les résultats.
Si vous n'avez pas connaissance du répertoire courant, l'étape 1 échouera probablement avec un code d'erreur « ImportError ». Pourquoi ? Parce que Python va chercher le module exemple dans le dossier de recherche de modules , mais il ne le trouvera pas car le dossier `exemples` ne fait pas partie des répertoires du dossier de recherche. Pour surmonter ce problème, vous pouvez faire l'une des deux choses suivantes :
- ajouter le répertoire « exemples » au dossier de recherche de modules ;
- changer le répertoire courant pour celui du dossier « exemples ».
Le répertoire courant est une propriété invisible que Python garde en mémoire à tout instant. Il y a toujours un répertoire courant, que vous soyez dans le Shell Python, que vous fassiez tourner votre propre script Python en ligne de commande ou que vous fassiez tourner un script Python CGI (Common Gateway Interface) sur un serveur web quelque part.
Le module os dispose de deux fonctions pour travailler avec le répertoire courant.
2.
3.
4.
5.
6.
7.
8.
python
>>>
import
os
>>>
print
(
os.getcwd
(
))
C:\Python31
>>>
os.chdir
(
'/Users/pilgrim/diveintopython3/exemples'
)
>>>
print
(
os.getcwd
(
))
C:\Users\pilgrim\diveintopython3\exemples
```
- ligne 2 : le module os de la bibliothèque standard de Python ; vous pouvez l'importer à n'importe quel moment, n'importe où ;
- ligne 3 : utilise la fonction os.getcwd() afin d'obtenir le répertoire courant. Lorsque vous lancez le Shell Python, le répertoire courant débute par le répertoire où se situe l'exécutable du Shell. Sur Windows, cela dépend de l'emplacement où vous avez installé Python ; le répertoire par défaut est ici `C:\Python31`. Si vous lancez le Shell Python en ligne de commande, le répertoire courant débute par le répertoire où vous étiez lorsque vous aviez lancé `python3` ;
- ligne 5 : utilise la fonction os.chdir() pour modifier le répertoire courant. Lorsque j'ai appelé la fonction os.chdir(), j'ai utilisé un chemin de type Linux (des slashs (/) et non des backslashs (\) et pas de lettre pour le disque) même si je suis sur Windows. C'est l’un des cas où Python essaie de masquer les écarts entre les différents systèmes d'exploitation.
IV-B-2. Travailler avec des noms de fichiers et de dossiers▲
Tant qu'à traiter du sujet des répertoires, je voudrais évoquer le module os.path. os.path contient des fonctions pour manipuler les noms de fichiers et de dossiers.
2.
3.
4.
5.
6.
7.
8.
9.
10.
python
>>>
import
os
>>>
print
(
os.path.join
(
'/Users/pilgrim/diveintopython3/exemples/'
, 'humansize.py'
))
/
Users/
pilgrim/
diveintopython3/
exemples/
humansize.py
>>>
print
(
os.path.join
(
'/Users/pilgrim/diveintopython3/exemples'
, 'humansize.py'
))
/
Users/
pilgrim/
diveintopython3/
exemples\humansize.py
>>>
print
(
os.path.expanduser
(
'~'
))
c:\Users\pilgrim
>>>
print
(
os.path.join
(
os.path.expanduser
(
'~'
), 'diveintopython3'
, 'exemples'
, 'humansize.py'
))
c:\Users\pilgrim\diveintopython3\exeples\humansize.py
- ligne 3 : la fonction os.path.join() construit un nom de chemin à partir d'un ou plusieurs chemins partiels. Dans le cas présent, il concatène simplement des chaînes de caractères ;
- ligne 5 : dans ce cas légèrement moins trivial, appeler la fonction os.path.join() ajoutera un slash supplémentaire au nom du chemin avant d'ajouter le nom du fichier. C'est un backslash (`\`) au lieu d'un slash (`/`), car j'ai construit cet exemple sur Windows. Si vous reproduisez cet exemple sur Linux ou Max OS X, vous obtiendrez un slash à la place. Ne vous embêtez pas avec les slashes, préférez l'utilisation de os.path.join() et laissez Python faire ce qu'il faut pour vous ;
- ligne 7 : la fonction os.path.expanduser() va étendre un nom du répertoire qui utilise « ~ » pour représenter le répertoire par défaut de l'utilisateur courant (NDT : répertoire home). Cela fonctionne sur n'importe quelle plate-forme où l'utilisateur possède un répertoire par défaut, incluant Linux, Mac OS X et Windows. Le chemin retourné ne possède pas de slash à la fin, mais cela n'a aucune importance pour os.path.join() ;
- ligne 9 : en combinant ces techniques, vous pouvez aisément construire des noms de chemin pour dossiers et fichiers dans le répertoire par défaut de l'utilisateur. La fonction os.path.join() peut prendre un nombre indéfini d'arguments. J'étais plus que ravi lorsque j'ai découvert cela, addSlashIfNecessary() est l’une de ces petites fonctions stupides que j'ai toujours besoin d'écrire quand je développe ma boite à outils dans un nouveau langage. *N'écrivez pas* cette fonction stupide en Python ; des gens intelligents ont déjà pris soin de le faire pour vous.
os.path contient également des fonctions pour diviser un chemin entier, des noms de dossiers et de fichiers, en leur constituants élémentaires.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
```python
>>>
pathname =
'/Users/pilgrim/diveintopython3/exemples/humansize.py'
>>>
os.path.split
(
pathname)
(
'/Users/pilgrim/diveintopython3/exemples'
, 'humansize.py'
)
>>>
(
dirname, filename) =
os.path.split
(
pathname)
>>>
dirname
'/Users/pilgrim/diveintopython3/exemples'
>>>
filename
'humansize.py'
>>>
(
shortname, extension) =
os.path.splitext
(
filename)
>>>
shortname
'humansize'
>>>
extension
'.py'
- ligne 1 : la fonction split() divise un nom de chemin entier et retourne un tuple contenant le chemin et le nom de fichier ;
- vous vous rappelez quand je disais que vous pouviez assigner plusieurs variables à la fois à la sortie d'une fonction ? La fonction os.path.split() fait exactement cela. Vous assignez la valeur de retour de la fonction split() dans un tuple de deux variables. Chaque variable reçoit la valeur correspondant à l'élément du tuple renvoyé ;
- ligne 5 : la première variable, dirname, reçoit la valeur du premier élément du tuple retourné par os.path.split(), le chemin du fichier ;
- la seconde variable, filename, reçoit la valeur du second élément du tuple retourné par os.path.split(), le nom du fichier ;
- ligne 10 : os.path comprend la fonction os.path.splitext(), qui découpe un nom de fichier et retourne un tuple contenant le nom du fichier et son extension. Vous pouvez utiliser la même technique pour les assigner à des variables séparées.
IV-B-3. Lister des répertoires▲
Le module glob est un autre outil de la bibliothèque standard de Python. C'est un moyen facile de récupérer le contenu d'un répertoire d'un point de vue programmation et il utilise le type de caractères de remplacement dont vous êtes peut-être déjà familier si vous travaillez en ligne de commande.
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.
python
>>>
os.chdir
(
'/Users/pilgrim/diveintopython3/'
)
>>>
import
glob
>>>
glob.glob
(
'exemples/*.xml'
)
['exemples
\\
feed-broken.xml'
,
'exemples
\\
feed-ns0.xml'
,
'exemples
\\
feed.xml'
]
>>>
os.chdir
(
'exemples/'
)
>>>
glob.glob
(
'*test*.py'
)
['alphameticstest.py'
,
'pluraltest1.py'
,
'pluraltest2.py'
,
'pluraltest3.py'
,
'pluraltest4.py'
,
'pluraltest5.py'
,
'pluraltest6.py'
,
'romantest1.py'
,
'romantest10.py'
,
'romantest2.py'
,
'romantest3.py'
,
'romantest4.py'
,
'romantest5.py'
,
'romantest6.py'
,
'romantest7.py'
,
'romantest8.py'
,
'romantest9.py'
]
- ligne 4 : le module glob prend un caractère de remplacement et retourne le chemin de tous les fichiers et répertoires correspondants. Dans cet exemple, le caractère de remplacement est le chemin d'un répertoire plus « '*.xml », ce qui correspondra à tous les fichiers ayant l'extension « .xml » dans le sous-répertoire « exemples » ;
- ligne 8 : remplace maintenant le répertoire courant par le répertoire « exemples ». La fonction os.chdir() peut prendre des noms de chemins relatifs ;
- ligne 9 : vous pouvez inclure plusieurs caractères de remplacement pour votre motif de recherche (NDT: « search pattern » en anglais). Cet exemple trouve tous les fichiers dans le répertoire courant qui finissent par l'extension « .py » et qui contiennent le mot `test` n'importe où dans leur nom.
IV-B-4. Récupérer les métadonnées d'un fichier▲
Tous les systèmes de fichiers modernes gardent en mémoire les métadonnées de chaque fichier : date de création, date de dernière modification, taille, etc. Python fourni une API unique pour accéder à ces données. Vous n'avez pas besoin d'ouvrir le fichier ; tout ce dont vous avez besoin est son nom.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
```python
>>>
import
os
>>>
print
(
os.getcwd
(
))
c:\Users\pilgrim\diveintopython3\exemples
>>>
metadata =
os.stat
(
'feed.xml'
)
>>>
metadata.st_mtime
1247520344.9537716
>>>
import
time
>>>
time.localtime
(
metadata.st_mtime)
time.struct_time
(
tm_year=
2009
, tm_mon=
7
, tm_mday=
13
, tm_hour=
17
,
tm_min=
25
, tm_sec=
44
, tm_wday=
0
, tm_yday=
194
, tm_isdst=
1
)
- ligne 3 : le répertoire courant est le dossier « exemples » ;
- ligne 5 : « `feed.xml » est un fichier du dossier « exemples ». Appeler la fonction os.stat() renvoie un objet qui contient plusieurs types différents de métadonnées à propos du fichier ;
- ligne 6 : st_mtime est la date de modification, mais dans un format qui n'est pas très utile. (Techniquement, c'est le nombre de secondes depuis « l'époque » (NDT: « Epoch time »), qui est définie comme la première seconde du 1er Janvier 1970. ) ;
- ligne 8 : le module time fait partie de la bibliothèque standard. Il contient des fonctions pour convertir différentes représentations temporelles, pour formater des valeurs temporelles en chaînes de caractères et gérer les fuseaux horaires ;
- ligne 9 : la fonction time.localtime() convertit la valeur temporelle des secondes depuis « l'époque » (à partir de l'attribut st_mtime retourné par la fonction os.stat()) dans une forme plus utile en années, mois, jours, heures, minutes, secondes, etc. Ce fichier a été modifié la dernière fois le 13 Juillet 2009, aux environs de 17h25 ;
2.
3.
4.
5.
6.
7.
8.
```python
# suite de l'exemple précédent
>>>
metadata.st_size
3070
>>>
import
humansize
>>>
humansize.approximate_size
(
metadata.st_size)
'3.0 KiB'
```
- ligne 3 : la fonction os.stat() retourne également la taille du fichier, grâce à l'attribut st_size. Le fichier « feed.xml » fait 3070 octets ;
- ligne 6: vous pouvez passer l'attribut st_size à la fonction approximate_size().
IV-B-5. Construire un chemin absolu▲
Dans les précédentes sectionsRécupérer les métadonnées d'un fichier, la fonction glob.glob() retournait une liste de chemins relatifs. Le premier exemple avait un chemin similaire à exemples\feed.xml et le second exemple avait un chemin relatif encore plus court comme romantest.py. Aussi longtemps que vous resterez dans le même répertoire courant, ces chemins relatifs fonctionneront pour ouvrir des fichiers et récupérer leurs métadonnées. Mais si vous souhaitez construire un chemin absolu, c'est-à-dire un chemin qui inclut tout le chemin du répertoire jusqu'à sa racine ou le nom du disque, alors vous aurez besoin de la fonction os.path.realpath().
2.
3.
4.
5.
6.
python
>>>
import
os
>>>
print
(
os.getcwd
(
))
c:\Users\pilgrim\diveintopython3\exemples
>>>
print
(
os.path.realpath
(
'feed.xml'
))
c:\Users\pilgrim\diveintopython3\exemples\feed.xml
IV-C. Compréhensions de listes (liste_intention)▲
Une compréhension de liste permet de créer une liste à partir d’une autre liste de façon compacte en appliquant une fonction à chaque élément de la liste initiale.
2.
3.
4.
5.
6.
7.
8.
9.
python
>>>
a_list =
[1
, 9
, 8
, 4
]
>>>
[elem *
2
for
elem in
a_list]
[2
, 18
, 16
, 8
]
>>>
a_list
[1
, 9
, 8
, 4
]
>>>
a_list =
[elem *
2
for
elem in
a_list]
>>>
a_list
[2
, 18
, 16
, 8
]
- ligne 3 : afin de donner du sens à cette ligne, lisez-là de droite à gauche. a_list est la liste que vous créez. L’interpréteur Python parcours a_list un élément à la fois, assigne temporairement la valeur de chaque élément à la variable elem. Python applique ensuite la fonction elem * 2 et ajoute le résultat à la liste retournée ;
- ligne 5 : une compréhension de liste crée une nouvelle liste; elle ne change pas l'originale ;
- ligne 7 : assigner le résultat d'une compréhension de liste à une variable que vous êtes en train de mapper est sans danger. Python crée une nouvelle liste en mémoire et lorsque la création de la compréhension de liste est terminée, il assigne le résultat à la variable originale.
Vous pouvez utiliser n'importe quelle expression dans une compréhension de liste, y compris les fonctions du module os pour manipuler des fichiers et répertoires.
2.
3.
4.
5.
6.
7.
8.
python
>>>
import
os, glob
>>>
glob.glob
(
'*.xml'
)
['feed-broken.xml'
, 'feed-ns0.xml'
, 'feed.xml'
]
>>>
[os.path.realpath
(
f) for
f in
glob.glob
(
'*.xml'
)]
['c:
\\
Users
\\
pilgrim
\\
diveintopython3
\\
exemples
\\
feed-broken.xml'
,
'c:
\\
Users
\\
pilgrim
\\
diveintopython3
\\
exemples
\\
feed-ns0.xml'
,
'c:
\\
Users
\\
pilgrim
\\
diveintopython3
\\
exemples
\\
feed.xml'
]
- ligne 3 : ceci retourne une liste de tous les fichiers avec l'extension .xml du répertoire courant ;
- ligne 5 : cette compréhension de liste prend la liste de tous les fichiers avec l'extension .xml et la transforme en liste de chemins absolus.
Les compréhensions de listes peuvent également filtrer certains éléments, produisant un résultat qui peut être plus court que la liste originale.
2.
3.
4.
5.
6.
7.
8.
9.
python
>>>
import
os, glob
>>>
[f for
f in
glob.glob
(
'*.py'
) if
os.stat
(
f).st_size >
6000
]
['pluraltest6.py'
,
'romantest10.py'
,
'romantest6.py'
,
'romantest7.py'
,
'romantest8.py'
,
'romantest9.py'
]
- ligne 3 : pour filtrer une liste, vous pouvez inclure une condition à la fin de la compréhension de liste. L'expression après le mot clef if va évaluer chaque élément de la liste. Si l'expression est évaluée comme vraie (True), l'élément sera inclus dans la sortie. Cette expression examine tous les fichiers .py du répertoire courant, et la condition if filtre cette liste en testant si la taille de chaque fichier est plus grande que 6000 octets. Il y a six fichiers satisfaisant ce critère, donc la compréhension de liste retourne une liste de six noms de fichiers.
Tous les exemples de compréhensions de listes présentés jusqu'à présent contenaient des expressions simples : multiplier un nombre par une constante, appeler une seule fonction ou simplement retourner les éléments de la liste originelle (après filtrage). Mais il n'y a pas de limite à la complexité que peut avoir une compréhension de liste.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
python
>>>
import
os, glob
>>>
[(
os.stat
(
f).st_size, os.path.realpath
(
f)) for
f in
glob.glob
(
'*.xml'
)] 1
[(
3074
, 'c:
\\
Users
\\
pilgrim
\\
diveintopython3
\\
exemples
\\
feed-broken.xml'
),
(
3386
, 'c:
\\
Users
\\
pilgrim
\\
diveintopython3
\\
exemples
\\
feed-ns0.xml'
),
(
3070
, 'c:
\\
Users
\\
pilgrim
\\
diveintopython3
\\
exemples
\\
feed.xml'
)]
>>>
import
humansize
>>>
[(
humansize.approximate_size
(
os.stat
(
f).st_size), f) for
f in
glob.glob
(
'*.xml'
)] 2
[(
'3.0 KiB'
, 'feed-broken.xml'
),
(
'3.3 KiB'
, 'feed-ns0.xml'
),
(
'3.0 KiB'
, 'feed.xml'
)]
- cette compréhension de liste trouve tous les fichiers .xml du répertoire courant, récupère la taille de chaque fichier (en appelant la fonction os.stat()) et construit un tuple avec la taille et le chemin absolu de chaque fichier (en appelant la fonction os.path.realpath()) ;
- cette compréhension de liste construite sur la base de la précédente appelle la [fonction approximate_size()] avec la taille de chaque fichier .xlm.
IV-D. Compréhensions de dictionnaires▲
Une compréhension de dictionnaire est comme une compréhension de liste, mais elle construit un dictionnaire en lieu et place d'une liste.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
python
>>>
import
os, glob
>>>
metadata =
[(
f, os.stat
(
f)) for
f in
glob.glob
(
'*test*.py'
)]
>>>
metadata[0
]
(
'alphameticstest.py'
, nt.stat_result
(
st_mode=
33206
, st_ino=
0
, st_dev=
0
,
st_nlink=
0
, st_uid=
0
, st_gid=
0
, st_size=
2509
, st_atime=
1247520344
,
st_mtime=
1247520344
, st_ctime=
1247520344
))
>>>
metadata_dict =
{f:os.stat
(
f) for
f in
glob.glob
(
'*test*.py'
)}
>>>
type(
metadata_dict)
<
class
'dict'
>
>>>
list(
metadata_dict.keys
(
))
['romantest8.py'
, 'pluraltest1.py'
, 'pluraltest2.py'
, 'pluraltest5.py'
,
'pluraltest6.py'
, 'romantest7.py'
, 'romantest10.py'
, 'romantest4.py'
,
'romantest9.py'
, 'pluraltest3.py'
, 'romantest1.py'
, 'romantest2.py'
,
'romantest3.py'
, 'romantest5.py'
, 'romantest6.py'
, 'alphameticstest.py'
,
'pluraltest4.py'
]
>>>
metadata_dict['alphameticstest.py'
].st_size
2509
- ligne 3 : ceci n'est pas une compréhension de dictionnaire, c'est une compréhension de liste (liste_intention). Elle trouve tous les fichier avec l'extension .py avec « test » dans leur nom, puis construit un tuple composé du nom du fichier et de ses métadonnées (en appelant la fonction os.stat()) ;
- ligne 4 : chaque élément retourné de la liste est un tuple ;
- ligne 8 : ceci est une compréhension de dictionnaire. La syntaxe est similaire à celle d'une compréhension de liste, avec deux différences. Premièrement, elle est entourée d'accolades au lieu de crochets. Deuxièmement, à la place d'une seule expression pour chaque élément, elle contient deux expressions séparées par deux points (« : »). L'expression avant les deux points (« f » dans cet exemple) est la clef du dictionnaire ; l'expression après les deux points (os.stat(f) dans cet exemple) est la valeur ;
- ligne 9 : une compréhension de dictionnaire renvoie un dictionnaire ;
- ligne 11 : les clefs de ce dictionnaire sont simplement les noms des fichiers renvoyés par l'appel à glob.glob('*test*.py') ;
- ligne 17 : la valeur associée à chaque clef est la sortie de la fonction os.stat(). Cela signifie que nous pouvons chercher un fichier par son nom dans ce dictionnaire afin de récupérer ses métadonnées. Un des éléments des métadonnées est l'attribut st_size, la taille du fichier. Le fichier alphameticstest.py fait ainsi 2509 octets.
Comme pour les compréhensions de listes, vous pouvez définir une condition dans une compréhension de dictionnaire afin de filtrer les entrées de la séquence en se basant sur une expression évaluée pour chaque élément.
2.
3.
4.
5.
6.
7.
8.
9.
10.
```python
>>>
import
os, glob, humansize
>>>
metadata_dict =
{f:os.stat
(
f) for
f in
glob.glob
(
'*'
)} 1
>>>
humansize_dict =
{os.path.splitext
(
f)[0
]:humansize.approximate_size
(
meta.st_size) \
... for
f, meta in
metadata_dict.items
(
) if
meta.st_size >
6000
} 2
>>>
list(
humansize_dict.keys
(
)) 3
['romantest9'
, 'romantest8'
, 'romantest7'
, 'romantest6'
, 'romantest10'
, 'pluraltest6'
]
>>>
humansize_dict['romantest9'
] 4
'6.5 KiB'
```
- cette compréhension de dictionnaire construit une liste de tous les fichiers du répertoire courant (glob.glob('*')), récupère les métadonnées de chaque fichier (os.stat(f)) et construit un dictionnaire dont les clefs sont les noms des fichiers et les valeurs les métadonnées ;
- cette compréhension de dictionnaire construite à partir de la précédente, filtre et ne retient pas les fichiers ayant une taille inférieure à 6000 octets (if meta.st_size > 6000). Elle utilise la liste filtrée pour construire un dictionnaire dont les clefs sont les noms de fichiers sans l'extension (os.path.splitext(f)[0]) et dont les valeurs sont la taille approchée des fichiers (humansize.approximate_size(meta.st_size)) ;
- comme vous avez pu le voir dans l'exemple précédent, il y a six fichiers d'une taille supérieure à 6000 octets, ainsi il y a six éléments dans ce dictionnaire ;
- la valeur associée à chaque clef est une chaîne de caractères renvoyée par la fonction approximate_size().
IV-D-1. D'autres choses sympathiques à faire avec les compréhensions de dictionnaires▲
Voici une astuce avec les compréhensions de dictionnaires pouvant s'avérer utile : interchanger les clefs et valeurs d'un dictionnaire.
2.
3.
4.
python
>>>
a_dict =
{'a'
: 1
, 'b'
: 2
, 'c'
: 3
}
>>>
{value:key for
key, value in
a_dict.items
(
)}
{1
: 'a'
, 2
: 'b'
, 3
: 'c'
}
Bien entendu, cela ne fonctionne que si les valeurs du dictionnaire sont non mutables, comme les chaînes de caractères ou les tuples. Si vous souhaitez essayer ceci avec un dictionnaire qui contient des listes, cela échouera superbement :
2.
3.
4.
5.
6.
7.
python
>>>
a_dict =
{'a'
: [1
, 2
, 3
], 'b'
: 4
, 'c'
: 5
}
>>>
{value:key for
key, value in
a_dict.items
(
)}
Traceback (
most recent call last):
File "<stdin>"
, line 1
, in
<
module>
File "<stdin>"
, line 1
, in
<
dictcomp>
TypeError
: unhashable type: 'list'
IV-E. Compréhensions de sets▲
À ne pas oublier : les sets ont également leur propre syntaxe en compréhension. Elles sont remarquablement similaires à celle des compréhensions de dictionnaires. La seule différence est que les sets n'ont que des *valeurs* en lieu et place des paires clef/valeur des dictionnaires.
- ligne 5 : les compréhensions de sets peuvent prendre un set en entrée. Cette compréhension de set calcule le carré d'un set de nombres de 0 à 9 ;
- ligne 7 : tout comme les compréhensions de listes et les compréhensions de dictionnaires, les compréhensions de sets peuvent contenir une clause conditionnelle if afin de filtrer chaque élément avant de le retourner dans le set résultat ;
- ligne 9 : les compréhensions de sets n'ont pas besoin de prendre un set en entrée, elles peuvent prendre n'importe quelle séquence.
IV-F. Lectures pour aller plus loin▲
- le module os.
- os - Accès portable aux fonctionnalités spécifiques au système d'exploitation.
- le module os.path.
- le module glob.
- glob - Recherche de motifs des noms de fichiers.
- le module time.
- time - Fonctions pour manipuler le temps horloge.