List Comprehension
List Comprehensions
Bienvenue dans la leçon sur les list comprehensions (syntaxe courte pour créer une liste) !
La Documentation se trouve dans la section 5.1.3
Contenu
Nous allons apprendre :
- pourquoi on en a besoin,
- de la structure de base à une version plus avancée,
- comment écrire une dictionary comprehension (syntaxe courte pour créer un dictionnaire).
Prêt à commencer ? Avant de continuer ta lecture, assure-toi d'avoir terminé les quêtes suivantes :
A-t-on besoin des list comprehensions ??
Dans la Data, on fait généralement face à d'énormes quantités de valeurs qu'on doit traiter assez vite (dans certains cas extrêmes, "assez vite" veut dire "en moins d'une semaine". Dingue, non ?). Il existe plusieurs options, côté matériel comme côté logiciel, qui peuvent nous aider à améliorer le temps de traitement. Par exemple le GPU, Pandas et la programmation fonctionnelle. La première étape pour les utiliser efficacement, c'est d'arrêter de penser "valeur par valeur" (ou "une donnée après l'autre") et de commencer à penser "toutes les données d'un coup".
Passer du traitement d'une valeur au traitement de toutes les valeurs d'un coup : change ton point de vue !
L'une des principales différences entre la Data et le développement logiciel, côté code, c'est la quantité d'informations traitées en même temps. Les développeurs logiciels manipulent des variables qui occupent très peu de mémoire à la fois. En général, c'est une valeur ou un appel d'instance pour un traitement. Les gens de la Data traitent d'énormes quantités d'informations toutes en même temps, donc ils doivent réfléchir à comment tout traiter (ou la plupart) en une seule fois.
Regardons le code suivant. Admettons qu'on a une list de nombres et qu'on doit les mettre au carré.
some_list_of_numbers = [0, 1, 2, 3, 4, 5]
new_list_of_numbers = []
for number in some_list_of_numbers:
new_list_of_numbers += [number ** 2]
new_list_of_numbers
Dans cet extrait de code, la boucle for prend chaque valeur, la met au carré, l'ajoute à la nouvelle list, puis passe à la valeur suivante. Donc la personne qui écrit considère le traitement de chaque valeur l'une après l'autre, puis les remet chacune dans une list.
L'objectif d'un code orienté Data avec de bonnes performances, c'est de traiter toutes les valeurs d'un coup. Si ce n'est pas possible, au moins des groupes de valeurs à la fois. Comment on fait ça ? On déplace l'attention de ce qui arrive à une valeur vers ce qui arrive à toutes les valeurs en même temps.
Pour l'exemple précédent :
some_list_of_numbers = [0, 1, 2, 3, 4, 5]
new_list_of_numbers = [number ** 2 for number in some_list_of_numbers]
new_list_of_numbers
Maintenant, on ne voit plus le traitement de chaque nombre, on se concentre juste sur la list entière.
Un autre avantage, c'est que sans indentation le code est plus facile à lire. Avec des codes plus longs, ce sera plus facile à suivre pour les yeux.
Voyons ce qui s'est passé avec un exemple de la vie réelle.
Avant de commencer, revoyons quelques concepts dont on a besoin :
Les opérateurs ternaires
Le job des comprehensions !
Notre entreprise a trouvé un nouveau client et on se lance sur le projet !!

Notre client est une entreprise immobilière qui possède plusieurs immeubles en centre-ville. Les bureaux des immeubles qu'ils possèdent ont des capteurs, et le manager veut connaître la température moyenne par jour. Les capteurs viennent d'être installés et ils ont les données du dernier mois. Les capteurs enregistrent une mesure en Kelvin toutes les cinq minutes, donc on doit faire la moyenne par jour et présenter nos résultats. Le client veut les résultats en Celsius.
List Comprehension : structure de base
Une fois qu'on a la température moyenne par jour, on doit la convertir en Kelvin, comme demandé dans les spécifications.
Ce qu'un développeur logiciel écrirait :
temperature_in_kelvin = [301.15, 301.15, 303.15, 300.15, 301.15, 302.15, 324.15, 294.15, 301.15, 300.15, 297.15, 299.15, 302.15, 286.15, 301.15, 300.15, 298.15, 329.15, 299.15, 289.15, 299.15, 299.15, 299.15, 301.15, 301.15, 292.15, 300.15, 289.15, 299.15, 298.15, 298.15]
temperature_in_celsius = []
for t in temperature:
temperature_in_celsius += [int(t - 273.15)]
print(temperature_in_celsius)
Revoyons la règle pour passer d'une boucle à une list comprehension :
Comment transformer ce code en quelque chose qu'un professionnel de la Data écrirait :
temperature_in_celsius = [int(t - 273.15) for t in temperature]
print(temperature_in_celsius)
List Comprehension : structure de base avec une fonction
Le client s'est trompé ! Ils viennent de nous dire que la mesure vraiment demandée, c'est le Fahrenheit. Utilisons la formule pour convertir des Celsius en Fahrenheit :
$fahren = (celsius) * 9 / 5 + 32$
pour transformer les valeurs en Celsius en Fahrenheit
def cels_to_fahren(temp):
return temp * 9 / 5 + 32
temperature_in_fahren = [cels_to_fahren (t) for t in temperature_in_celsius]
print(temperature_in_fahren)
List Comprehension : structure avec un filtre
On est retournés voir notre client pour un retour. Ils ont regardé les chiffres et se sont rendu compte que certains étaient assez élevés. Ils ont compris que ça devait être des mesures erronées et veulent les retirer. Ils veulent que les valeurs supérieures à 39°C soient effacées de la list. Apparemment, ça ne les dérange pas d'avoir moins de valeurs dans la list, puisqu'il devrait y avoir une valeur par jour du mois dernier.
On doit filtrer la list de façon à ce que seules les valeurs qui satisfont la condition puissent être traitées et ajoutées à la nouvelle list.
temperature_in_fahren = []
def cels_to_fahren(temp):
return temp * 9 / 5 + 32
for t in temperature_in_celsius:
if t < 40:
temperature_in_fahren += [cels_to_fahren(t)]
print(temperature_in_fahren)
Utilisons cette règle :
et écrivons le code avec une list comprehension :
def cels_to_fahren(temp):
return temp * 9 / 5 + 32
temperature_in_fahren = [cels_to_fahren (t) for t in temperature_in_celsius if t < 40]
print(temperature_in_fahren)
List Comprehension : structure avec des conditions
Nos clients sont de retour. Ils ont vu le résultat et demandent quelques modifications supplémentaires. Certaines valeurs sont clairement fausses, leurs capteurs enregistrent une température trop basse. Maintenant ils veulent que toutes les valeurs en dessous de 68°F soient remplacées par 68°F.
Pour ça, on va ajouter une condition if à la valeur, en suivant cette règle :
Comme tu peux le voir, le deuxième if s'écrit comme un ternary operator (opérateur ternaire). Heureusement qu'on vient juste de réviser ça !
def cels_to_fahren(temp):
return temp * 9 / 5 + 32
temperature_in_fahren = [cels_to_fahren(t) for t in temperature_in_celsius]
# Additional list comprehension
temperature_checked = [t if t >= 68 else 68.0 for t in temperature_in_fahren]
print(temperature_checked)
Mettons tout ensemble
Nos clients sont maintenant satisfaits et on va améliorer la lisibilité du code.
C'est normal d'écrire plus de lignes de code au début et d'essayer d'en réduire le nombre plus tard. Faisons pareil.
def cels_to_fahren(temp):
return temp * 9 / 5 + 32
temperature_processed = [cels_to_fahren(t) if cels_to_fahren(t) >= 68 else 68.0 for t in temperature_in_celsius if t < 40]
print(temperature_processed)
Dictionary Comprehensions
De la même façon, les dictionary comprehensions sont plus rapides à écrire et produisent un code plus rapide à lire. Tout le code sera plus facile à comprendre. Continuons avec notre exemple.
Nos clients sont de retour et veulent savoir pour combien de jours du mois on a chaque température. On va répondre à cette question avec une dictionary comprehension.
day_count = {t : temperature_processed.count(t) for t in set(temperature_processed)}
print(day_count)
Peux-tu deviner la règle que j'ai suivie pour la construire ?
true
# Est-ce la règle ? {k: v for v in list}
[x] Faux
[] Vrai
Ressources supplémentaires :
List Comprehensions, général
Listes imbriquées, avancé
List Comprehensions, vidéo avec exercices
Dictionary Comprehensions, complet avec exercices
Challenge
Bravo d'être arrivé jusqu'ici !
C'est l'heure du challenge !
Crée une copie de ce notebook et réalise les tâches dessus : lien vers colab.
Une fois que tu as terminé, poste un lien vers ton notebook comme solution pour validation, n'oublie pas de le partager pour que toute personne ayant le lien puisse le lire.
Critères de validation
- Le notebook est partagé de façon à être lisible par toute personne ayant le lien
- Les exercices ont été correctement codés
List Comprehensions
Welcome to the List Comprehension Lesson!
Documentation is in the section 5.1.3
Content
We are going to learn:
- why we need to use them,
- from the basic structure to a more advanced one,
- how to write a dictionary comprehension.
Ready to start? Before you keep reading, make sure you have completed the following quests:
Do we need list comprehensions??
In Data we are usually faced with huge amounts of values we need to process rather quickly (in some extreme cases "rather quickly" means "in less than a week". Crazy, ah?). There are multiple options, both hardware-wise and software-wise, that can help us improve the processing time. For example the GPU, Pandas, and functional programming. The first step to use them proficiently is to stop thinking "per value" (or "one piece of data after the next") and start thinking "all data at once".
From processing one value to processing all the values we have at once: change the focus!
On of the main differences between Data and Software Development, code-wise, is the amount of information processed at once. Software Developers have to do with variables that occupy very little memory space at once. Usually is a value or an instance-call for some process. Data people process huge amount of information all at once, so they need to think on how to process all of it - or most of it - in one go.
Let's look at the following code. Let's assume we have a list of numbers and we need to square them.
some_list_of_numbers = [0, 1, 2, 3, 4, 5]
new_list_of_numbers = []
for number in some_list_of_numbers:
new_list_of_numbers += [number ** 2]
new_list_of_numbers
In this code snippet, the for-loop considers each value and after squaring each of them, adds them to the new list, and then moves on to the next value. So the writer considers processing each value one after the other and then putting each of them back in a list.
The goal of a Data-oriented code with good performance is to process all the values at once. If that's not possible, at least groups of values at once. How do we do this? We shift the focus from what happens to one value to what happens to all of them at once.
For the previous example:
some_list_of_numbers = [0, 1, 2, 3, 4, 5]
new_list_of_numbers = [number ** 2 for number in some_list_of_numbers]
new_list_of_numbers
Now we don't see what is the processing of each number anymore, we are just focusing on the entire list.
An additional advantage is that without indentation the code is easier to read. With longer codes, it will be easier for the eyes to follow.
Let's see what has happened with a real life example.
Before starting, let's review some concepts we need:
Ternary operators
The Comprehensive Job!
Our company found a new client and we are getting in on the project!!

Our client is a real estate company and owns several buildings downtown. The offices in the buildings they own have sensors, and the manager wants to know the average temperature per day. The sensors have just been installed and they have the last month worth of data. The sensors record a reading in Kelvin every five minutes, so we need to average per day and present our findings. The client wants the results in Celsius.
List Comprehension - Basic structure
Once we got the average temperature per day, we need to turn it into Kelvin, as per specifications.
What a Software Developer will write:
temperature_in_kelvin = [301.15, 301.15, 303.15, 300.15, 301.15, 302.15, 324.15, 294.15, 301.15, 300.15, 297.15, 299.15, 302.15, 286.15, 301.15, 300.15, 298.15, 329.15, 299.15, 289.15, 299.15, 299.15, 299.15, 301.15, 301.15, 292.15, 300.15, 289.15, 299.15, 298.15, 298.15]
temperature_in_celsius = []
for t in temperature:
temperature_in_celsius += [int(t - 273.15)]
print(temperature_in_celsius)
Let's review the rule to pass from a loop to a list comprehension:
How to change this code in something a Data Professional would write:
temperature_in_celsius = [int(t - 273.15) for t in temperature]
print(temperature_in_celsius)
List Comprehension - Basic Structure using a Function
The client got it wrong! They just let us know the actual required metric is the Fahrenheit. Let's use the formula to convert from Celsius to Fahrenheit:
$fahren = (celsius) * 9 / 5 + 32$
to turn the Celsius values into Fahrenheit
def cels_to_fahren(temp):
return temp * 9 / 5 + 32
temperature_in_fahren = [cels_to_fahren (t) for t in temperature_in_celsius]
print(temperature_in_fahren)
List Comprehension - Structure using a Filter
We went back to our client for feedback. They looked at the numbers and realized that some of them were pretty high. They realized they must have been wrong readings and want them out. They want the values over 39°C erased from the list. Apparently they are not concern with having fewer values in the list, as there should be one value per day of the past month.
We need to filter the list in a way that only the values that satisfy the condition can be processes and added to the new list.
temperature_in_fahren = []
def cels_to_fahren(temp):
return temp * 9 / 5 + 32
for t in temperature_in_celsius:
if t < 40:
temperature_in_fahren += [cels_to_fahren(t)]
print(temperature_in_fahren)
Let's use this rule:
and write the code with a list comprehension:
def cels_to_fahren(temp):
return temp * 9 / 5 + 32
temperature_in_fahren = [cels_to_fahren (t) for t in temperature_in_celsius if t < 40]
print(temperature_in_fahren)
List Comprehension - Structure using Conditions
Our clients are back. They saw the result and are asking for some additional modifications. Some of the values are clearly wrong, they sensors are recording a temperature that is too low. Now they want that all the values below 68°F to be substituted with 68°F.
To do this we'll add a if condition to the value, following this rule:
As you can see the second if gets written as a ternary operator. Good thing we just had a refresher on that!
def cels_to_fahren(temp):
return temp * 9 / 5 + 32
temperature_in_fahren = [cels_to_fahren(t) for t in temperature_in_celsius]
# Additional list comprehension
temperature_checked = [t if t >= 68 else 68.0 for t in temperature_in_fahren]
print(temperature_checked)
Let's put it all together
Our clients are now satisfied and we are going to improve the legibility of the code.
It's normal to write more lines of code at first and try to reduce the number later on. Let's do the same.
def cels_to_fahren(temp):
return temp * 9 / 5 + 32
temperature_processed = [cels_to_fahren(t) if cels_to_fahren(t) >= 68 else 68.0 for t in temperature_in_celsius if t < 40]
print(temperature_processed)
Dictionary Comprehensions
In the same way, dictionary comprehensions are faster to write and produce code that is quicker to read. The whole code will be easier to understand. Let's keep using our example.
Our clients are back and want to know for how many days of the month we have each temperature. We are going to answer this question with a dictionary comprehension.
day_count = {t : temperature_processed.count(t) for t in set(temperature_processed)}
print(day_count)
Can you guess the rule I followed to build it?
true
# Is this the rule? {k: v for v in list}
[x] False
[] True
Additional Resources:
List Comprehensions , General
Nested Lists, Advanced
List Comprehensions, video with exercises
Dictionary Comprehensions, comprehensive with exercises
Challenge
Great job arriving here!
Now is challenge time!
Create a copy of this notebook and carry out the tasks on it: link to colab.
Once you are finished, post a link to your notebook as a solution for validation, don't forget to share it so that anyone who has the link can read it.
Validation criterias
- The notebook is shared so that is readable by anyone with the link
- The exercises have been correctly coded