import re
import os
import pandas as pd
import numpy as np

Introduction

Les listes en comprehension permettent de realiser des boucles avec une syntaxe compacte et lisible. Et comme un exemple vaut mieux qu’un long discours :

Exemples simples

La syntaxe est de la forme [<expression> for x in <iterable> if <condition>].

Ici on genere la liste des carres des entiers pairs <= 8.

[i*i for i in range(10) if i % 2 == 0]
[0, 4, 16, 36, 64]

On peut de la meme maniere generer des dictionnaires ou des ensembles, pourvu que les cles du dictionnaire ou les elements de l’ensemble soient distincts.

Un dictionnaire en comprehension.

cles = 'abcdef'
valeurs = range(10,15)
{cles[i]:valeurs[i] for i in range(5)}
{'a': 10, 'b': 11, 'c': 12, 'd': 13, 'e': 14}

On obtient le meme resultat avec zip.

dict(zip(cles, valeurs))
{'a': 10, 'b': 11, 'c': 12, 'd': 13, 'e': 14}

Un ensemble en comprehension.

{cles[i]  for i in range(5)}
{'a', 'b', 'c', 'd', 'e'}

Exemples avec des listes multiples

Construire une matrice a l’aide de listes imbriquees.

matrice = [[j + i for i in range(5)] for j in range(0, 30, 10)]
np.array(matrice)
array([[ 0,  1,  2,  3,  4],
       [10, 11, 12, 13, 14],
       [20, 21, 22, 23, 24]])

Aplatir une matrice a l’aide de deux for.

[k for liste in matrice for k in liste]
[0, 1, 2, 3, 4, 10, 11, 12, 13, 14, 20, 21, 22, 23, 24]

Lire un fichier

On cree d’abord un fichier simple en verifiant qu’il n’existe pas deja, pour eviter d’ecraser un fichier auquel vous tenez …

if not os.path.isfile('test.txt'):
  with open("test.txt", "x") as f:
    f.write('a\n')
    f.write('b,c\n')
    f.write('d,e,f')
2
4
5

Ici rstrip enleve les retours a la ligne.

[s for s in open("test.txt")]
['a\n', 'b,c\n', 'd,e,f']
[s.rstrip() for s in open("test.txt")]
['a', 'b,c', 'd,e,f']

On obtient les memes resultats avec readlines ou read.

with open("test.txt", "r") as text_file:
    liste = text_file.readlines()
liste
['a\n', 'b,c\n', 'd,e,f']

Et pour se debarrasser du \n.

with open("test.txt", "r") as text_file:
    liste = text_file.read().splitlines()
liste
['a', 'b,c', 'd,e,f']

Lister les objets de l’environnement

Cette methode est supeflue si vous codez dans un IDE qui fournit normalement une telle liste dans une fenetre, mais elle est utile si vous aimez les editeurs de code avec moins de fonctionnalites.

[x for x in dir() if not re.search("__", x)]
['R', 'cles', 'f', 'liste', 'matrice', 'np', 'os', 'pd', 'r', 're', 'sys', 'text_file', 'valeurs']

Breve comparaison avec R

On a des fonctionnalites un peu similaires dans R mais elles sont moins puissantes et conviviales. Elles consistent a appliquer une meme fonction aux differents elements d’un vecteur ou d’une liste.

Fonction sapply

Cette fonction est dangereuse a employer dans un code en production : R essaye de simplifier le type du resultat mais n’y parvient pas toujours, on peut donc aussi bien obtenir un vecteur qu’une liste. Mais cette fonction est pratique en mode “exploratoire rapide”.

Fonction qui retourne la classe de chaque colonne d’un dataframe. Ici un dataframe est traite comme la liste de ses colonnes, la version Python serait [dtf[colonne].dtype for colonne in dtf.columns].

# un vecteur de strings
sapply(iris, class)

iris2 = iris
iris2["date"] = Sys.time()

# une liste
sapply(iris2, class)
Sepal.Length  Sepal.Width Petal.Length  Petal.Width      Species 
   "numeric"    "numeric"    "numeric"    "numeric"     "factor" 
$Sepal.Length
[1] "numeric"

$Sepal.Width
[1] "numeric"

$Petal.Length
[1] "numeric"

$Petal.Width
[1] "numeric"

$Species
[1] "factor"

$date
[1] "POSIXct" "POSIXt" 

Fonction lapply

On est sur de recuperer une liste.

lapply(iris, class)
$Sepal.Length
[1] "numeric"

$Sepal.Width
[1] "numeric"

$Petal.Length
[1] "numeric"

$Petal.Width
[1] "numeric"

$Species
[1] "factor"

Fonction vapply

Cette fonction permet d’imposer le type et la dimension du resultat pour de la programmation rigoureuse, et elle permet d’obtenir en resultat des vecteurs, des matrices ou des arrays de dimension superieure.

vapply(iris, class, character(1))

try(vapply(iris2, class, character(1)))

vapply(iris[,1:4], function(x) c(min(x), max(x)), double(2))
Sepal.Length  Sepal.Width Petal.Length  Petal.Width      Species 
   "numeric"    "numeric"    "numeric"    "numeric"     "factor" 
Error in vapply(iris2, class, character(1)) : 
  les valeurs doivent être d'une longueur 1,
 mais FUN(X[[6]]) a une longueur 2
     Sepal.Length Sepal.Width Petal.Length Petal.Width
[1,]          4.3         2.0          1.0         0.1
[2,]          7.9         4.4          6.9         2.5

retour au debut du document