Différentes manières de représenter des enregistrements

PythonPythonIntermediate
Pratiquer maintenant

This tutorial is from open-source community. Access the source code

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Dans ce laboratoire (lab), vous apprendrez à explorer des méthodes économes en mémoire pour stocker de grands ensembles de données en Python. Vous découvrirez également différentes manières de représenter des enregistrements, telles que les tuples, les dictionnaires, les classes et les tuples nommés (named tuples).

De plus, vous comparerez l'utilisation mémoire de différentes structures de données. Comprendre les compromis entre ces structures est précieux pour les utilisateurs de Python qui effectuent des analyses de données, car cela aide à optimiser le code.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("Python")) -.-> python/FileHandlingGroup(["File Handling"]) python(("Python")) -.-> python/PythonStandardLibraryGroup(["Python Standard Library"]) python(("Python")) -.-> python/DataStructuresGroup(["Data Structures"]) python/DataStructuresGroup -.-> python/tuples("Tuples") python/DataStructuresGroup -.-> python/dictionaries("Dictionaries") python/FileHandlingGroup -.-> python/file_opening_closing("Opening and Closing Files") python/FileHandlingGroup -.-> python/file_reading_writing("Reading and Writing Files") python/FileHandlingGroup -.-> python/file_operations("File Operations") python/FileHandlingGroup -.-> python/with_statement("Using with Statement") python/PythonStandardLibraryGroup -.-> python/data_collections("Data Collections") subgraph Lab Skills python/tuples -.-> lab-132428{{"Différentes manières de représenter des enregistrements"}} python/dictionaries -.-> lab-132428{{"Différentes manières de représenter des enregistrements"}} python/file_opening_closing -.-> lab-132428{{"Différentes manières de représenter des enregistrements"}} python/file_reading_writing -.-> lab-132428{{"Différentes manières de représenter des enregistrements"}} python/file_operations -.-> lab-132428{{"Différentes manières de représenter des enregistrements"}} python/with_statement -.-> lab-132428{{"Différentes manières de représenter des enregistrements"}} python/data_collections -.-> lab-132428{{"Différentes manières de représenter des enregistrements"}} end

Exploration du jeu de données

Commençons notre exploration en examinant de près le jeu de données (dataset) avec lequel nous allons travailler. Le fichier ctabus.csv est un fichier CSV (Comma-Separated Values, valeurs séparées par des virgules). Les fichiers CSV sont une méthode courante pour stocker des données tabulaires, où chaque ligne représente une rangée, et les valeurs à l'intérieur d'une rangée sont séparées par des virgules. Ce fichier particulier contient des données quotidiennes sur l'achalandage du réseau de bus de la Chicago Transit Authority (CTA), couvrant la période du 1er janvier 2001 au 31 août 2013.

Dézippez le fichier et supprimez le fichier zip :

cd /home/labex/project
unzip ctabus.csv.zip
rm ctabus.csv.zip

Pour comprendre la structure de ce fichier, nous allons d'abord y jeter un coup d'œil. Nous utiliserons Python pour lire le fichier et afficher quelques lignes. Ouvrez un terminal et exécutez le code Python suivant :

f = open('/home/labex/project/ctabus.csv')
print(next(f))  ## Lit la ligne d'en-tête (header)
print(next(f))  ## Lit la première ligne de données
print(next(f))  ## Lit la deuxième ligne de données
f.close()

Dans ce code, nous ouvrons d'abord le fichier en utilisant la fonction open et l'assignons à la variable f. La fonction next est utilisée pour lire la ligne suivante du fichier. Nous l'utilisons trois fois : la première fois pour lire la ligne d'en-tête (header), qui contient généralement les noms des colonnes dans le jeu de données (dataset). La deuxième et la troisième fois, nous lisons respectivement la première et la deuxième ligne de données. Enfin, nous fermons le fichier en utilisant la méthode close pour libérer les ressources du système.

Vous devriez voir une sortie similaire à ceci :

route,date,daytype,rides

3,01/01/2001,U,7354

4,01/01/2001,U,9288

Cette sortie montre que le fichier a 4 colonnes de données. Décomposons ce que chaque colonne représente :

  1. route : Il s'agit du nom ou du numéro de la ligne de bus. C'est la première colonne (Colonne 0) dans le jeu de données (dataset).
  2. date : C'est une chaîne de caractères (string) de date au format MM/JJ/AAAA. C'est la deuxième colonne (Colonne 1).
  3. daytype : C'est un code de type de jour, qui est la troisième colonne (Colonne 2).
    • U = Dimanche/Jour férié (Sunday/Holiday)
    • A = Samedi (Saturday)
    • W = Jour de semaine (Weekday)
  4. rides : Cette colonne enregistre le nombre total de passagers sous forme d'entier (integer). C'est la quatrième colonne (Colonne 3).

La colonne rides nous indique combien de personnes sont montées dans un bus sur une ligne spécifique un jour donné. Par exemple, d'après la sortie ci-dessus, nous pouvons voir que 7 354 personnes ont pris le bus numéro 3 le 1er janvier 2001.

Maintenant, découvrons combien de lignes contient le fichier. Connaître le nombre de lignes nous donnera une idée de la taille de notre jeu de données (dataset). Exécutez le code Python suivant :

with open('/home/labex/project/ctabus.csv') as f:
    line_count = sum(1 for line in f)
    print(f"Total lines in the file: {line_count}")

Dans ce code, nous utilisons l'instruction with pour ouvrir le fichier. L'avantage d'utiliser with est qu'il se charge automatiquement de fermer le fichier lorsque nous avons terminé de l'utiliser. Nous utilisons ensuite une expression génératrice (1 for line in f) pour créer une séquence de 1, un pour chaque ligne du fichier. La fonction sum additionne tous ces 1, ce qui nous donne le nombre total de lignes dans le fichier. Enfin, nous affichons le résultat.

Cela devrait afficher environ 577 564 lignes, ce qui signifie que nous avons affaire à un jeu de données (dataset) important. Ce grand jeu de données (dataset) nous fournira de nombreuses données à analyser et à partir desquelles tirer des conclusions.

Mesure de l'utilisation mémoire avec différentes méthodes de stockage

Dans cette étape, nous allons examiner comment différentes manières de stocker des données peuvent avoir un impact sur l'utilisation mémoire. L'utilisation mémoire est un aspect important de la programmation, en particulier lorsqu'il s'agit de traiter de grands ensembles de données. Pour mesurer la mémoire utilisée par notre code Python, nous allons utiliser le module tracemalloc de Python. Ce module est très utile car il nous permet de suivre les allocations mémoire effectuées par Python. En l'utilisant, nous pouvons voir combien de mémoire nos méthodes de stockage de données consomment.

Méthode 1 : Stockage du fichier entier sous forme d'une seule chaîne de caractères

Commençons par créer un nouveau fichier Python. Accédez au répertoire /home/labex/project et créez un fichier nommé memory_test1.py. Vous pouvez utiliser un éditeur de texte pour ouvrir ce fichier. Une fois le fichier ouvert, ajoutez le code suivant. Ce code lira le contenu entier d'un fichier sous forme d'une seule chaîne de caractères et mesurera l'utilisation mémoire.

## memory_test1.py
import tracemalloc

def test_single_string():
    ## Start tracking memory
    tracemalloc.start()

    ## Read the entire file as a single string
    with open('/home/labex/project/ctabus.csv') as f:
        data = f.read()

    ## Get memory usage statistics
    current, peak = tracemalloc.get_traced_memory()

    print(f"File length: {len(data)} characters")
    print(f"Current memory usage: {current/1024/1024:.2f} MB")
    print(f"Peak memory usage: {peak/1024/1024:.2f} MB")

    ## Stop tracking memory
    tracemalloc.stop()

if __name__ == "__main__":
    test_single_string()

Après avoir ajouté le code, enregistrez le fichier. Maintenant, pour exécuter ce script, ouvrez votre terminal et exécutez la commande suivante :

python3 /home/labex/project/memory_test1.py

Lorsque vous exécutez le script, vous devriez voir une sortie similaire à ceci :

File length: 12361039 characters
Current memory usage: 11.80 MB
Peak memory usage: 23.58 MB

Les nombres exacts peuvent différer sur votre système, mais généralement, vous remarquerez que l'utilisation mémoire actuelle est d'environ 12 Mo et l'utilisation mémoire maximale d'environ 24 Mo.

Méthode 2 : Stockage sous forme de liste de chaînes de caractères

Ensuite, nous allons tester une autre manière de stocker les données. Créez un nouveau fichier nommé memory_test2.py dans le même répertoire /home/labex/project. Ouvrez ce fichier dans l'éditeur et ajoutez le code suivant. Ce code lit le fichier et stocke chaque ligne sous forme de chaîne de caractères distincte dans une liste, puis mesure l'utilisation mémoire.

## memory_test2.py
import tracemalloc

def test_list_of_strings():
    ## Start tracking memory
    tracemalloc.start()

    ## Read the file as a list of strings (one string per line)
    with open('/home/labex/project/ctabus.csv') as f:
        lines = f.readlines()

    ## Get memory usage statistics
    current, peak = tracemalloc.get_traced_memory()

    print(f"Number of lines: {len(lines)}")
    print(f"Current memory usage: {current/1024/1024:.2f} MB")
    print(f"Peak memory usage: {peak/1024/1024:.2f} MB")

    ## Stop tracking memory
    tracemalloc.stop()

if __name__ == "__main__":
    test_list_of_strings()

Enregistrez le fichier, puis exécutez le script en utilisant la commande suivante dans le terminal :

python3 /home/labex/project/memory_test2.py

Vous devriez voir une sortie similaire à ceci :

Number of lines: 577564
Current memory usage: 43.70 MB
Peak memory usage: 43.74 MB

Remarquez que l'utilisation mémoire a augmenté considérablement par rapport à la méthode précédente de stockage des données sous forme d'une seule chaîne de caractères. Cela s'explique par le fait que chaque ligne de la liste est un objet chaîne de caractères Python distinct, et chaque objet a son propre surcoût mémoire.

Compréhension de la différence de mémoire

La différence d'utilisation mémoire entre les deux approches montre un concept important en programmation Python appelé surcoût d'objet. Lorsque vous stockez des données sous forme de liste de chaînes de caractères, chaque chaîne est un objet Python distinct. Chaque objet a des exigences mémoire supplémentaires, qui comprennent :

  1. L'en-tête de l'objet Python (généralement 16 - 24 octets par objet). Cet en-tête contient des informations sur l'objet, comme son type et son compteur de références.
  2. La représentation de la chaîne de caractères elle - même, qui stocke les caractères de la chaîne.
  3. Le remplissage d'alignement mémoire. Il s'agit d'un espace supplémentaire ajouté pour garantir que l'adresse mémoire de l'objet est correctement alignée pour un accès efficace.

D'un autre côté, lorsque vous stockez le contenu entier du fichier sous forme d'une seule chaîne de caractères, il n'y a qu'un seul objet, et donc un seul ensemble de surcoûts. Cela le rend plus efficace en termes de mémoire lorsque l'on considère la taille totale des données.

Lors de la conception de programmes qui travaillent avec de grands ensembles de données, vous devez prendre en compte ce compromis entre l'efficacité mémoire et l'accessibilité des données. Parfois, il peut être plus pratique d'accéder aux données lorsqu'elles sont stockées dans une liste de chaînes de caractères, mais cela utilisera plus de mémoire. D'autres fois, vous pourriez privilégier l'efficacité mémoire et choisir de stocker les données sous forme d'une seule chaîne de caractères.

Travailler avec des données structurées à l'aide de tuples

Jusqu'à présent, nous avons traité du stockage de données textuelles brutes. Mais lorsqu'il s'agit d'analyse de données, nous devons généralement transformer les données en formats plus organisés et structurés. Cela facilite l'exécution de diverses opérations et l'obtention d'informations à partir des données. Dans cette étape, nous allons apprendre à lire les données sous forme de liste de tuples en utilisant le module csv. Les tuples sont une structure de données simple et utile en Python qui peut contenir plusieurs valeurs.

Création d'une fonction de lecture avec des tuples

Créons un nouveau fichier nommé readrides.py dans le répertoire /home/labex/project. Ce fichier contiendra le code pour lire les données à partir d'un fichier CSV et les stocker sous forme de liste de tuples.

## readrides.py
import csv
import tracemalloc

def read_rides_as_tuples(filename):
    '''
    Read the bus ride data as a list of tuples
    '''
    records = []
    with open(filename) as f:
        rows = csv.reader(f)
        headings = next(rows)     ## Skip headers
        for row in rows:
            route = row[0]
            date = row[1]
            daytype = row[2]
            rides = int(row[3])
            record = (route, date, daytype, rides)
            records.append(record)
    return records

if __name__ == '__main__':
    tracemalloc.start()

    rows = read_rides_as_tuples('/home/labex/project/ctabus.csv')

    current, peak = tracemalloc.get_traced_memory()
    print(f'Number of records: {len(rows)}')
    print(f'First record: {rows[0]}')
    print(f'Second record: {rows[1]}')
    print(f'Memory Use: Current {current/1024/1024:.2f} MB, Peak {peak/1024/1024:.2f} MB')

Ce script définit une fonction appelée read_rides_as_tuples. Voici ce qu'elle fait étape par étape :

  1. Elle ouvre le fichier CSV spécifié par le paramètre filename. Cela nous permet d'accéder aux données à l'intérieur du fichier.
  2. Elle utilise le module csv pour analyser chaque ligne du fichier. La fonction csv.reader nous aide à diviser les lignes en valeurs individuelles.
  3. Elle extrait les quatre champs (ligne de bus, date, type de jour et nombre de trajets) de chaque ligne. Ces champs sont importants pour notre analyse de données.
  4. Elle convertit le champ 'rides' en entier. Cela est nécessaire car les données dans le fichier CSV sont initialement au format chaîne de caractères, et nous avons besoin d'une valeur numérique pour les calculs.
  5. Elle crée un tuple avec ces quatre valeurs. Les tuples sont immuables, ce qui signifie que leurs valeurs ne peuvent pas être modifiées une fois qu'ils sont créés.
  6. Elle ajoute le tuple à une liste appelée records. Cette liste contiendra tous les enregistrements du fichier CSV.

Maintenant, exécutons le script. Ouvrez votre terminal et entrez la commande suivante :

python3 /home/labex/project/readrides.py

Vous devriez voir une sortie similaire à ceci :

Number of records: 577563
First record: ('3', '01/01/2001', 'U', 7354)
Second record: ('4', '01/01/2001', 'U', 9288)
Memory Use: Current 89.12 MB, Peak 89.15 MB

Remarquez que l'utilisation mémoire a augmenté par rapport à nos exemples précédents. Voici quelques raisons à cela :

  1. Nous stockons maintenant les données dans un format structuré (tuples). Les données structurées nécessitent généralement plus de mémoire car elles ont une organisation définie.
  2. Chaque valeur dans le tuple est un objet Python distinct. Les objets Python ont un certain surcoût, ce qui contribue à l'augmentation de l'utilisation mémoire.
  3. Nous avons une structure de liste supplémentaire qui contient tous ces tuples. Les listes occupent également de la mémoire pour stocker leurs éléments.

L'avantage d'utiliser cette approche est que nos données sont maintenant correctement structurées et prêtes pour l'analyse. Nous pouvons facilement accéder à des champs spécifiques de chaque enregistrement par index. Par exemple :

## Example of accessing tuple elements (add this to readrides.py file to try it)
first_record = rows[0]
route = first_record[0]
date = first_record[1]
daytype = first_record[2]
rides = first_record[3]
print(f"Route: {route}, Date: {date}, Day type: {daytype}, Rides: {rides}")

Cependant, l'accès aux données par index numérique n'est pas toujours intuitif. Il peut être difficile de se souvenir de quel index correspond à quel champ, surtout lorsqu'il y a un grand nombre de champs. Dans l'étape suivante, nous explorerons d'autres structures de données qui peuvent rendre notre code plus lisible et plus maintenable.

✨ Vérifier la solution et pratiquer

Comparaison de différentes structures de données

En Python, les structures de données sont utilisées pour organiser et stocker des données liées. Elles sont comme des conteneurs qui stockent différents types d'informations de manière structurée. Dans cette étape, nous allons comparer différentes structures de données et voir combien de mémoire elles utilisent.

Créons un nouveau fichier appelé compare_structures.py dans le répertoire /home/labex/project. Ce fichier contiendra le code pour lire des données à partir d'un fichier CSV et les stocker dans différentes structures de données.

## compare_structures.py
import csv
import tracemalloc
from collections import namedtuple

## Define a named tuple for rides data
RideRecord = namedtuple('RideRecord', ['route', 'date', 'daytype', 'rides'])

## A named tuple is a lightweight class that allows you to access its fields by name.
## It's like a tuple, but with named attributes.

## Define a class with __slots__ for memory optimization
class SlottedRideRecord:
    __slots__ = ['route', 'date', 'daytype', 'rides']

    def __init__(self, route, date, daytype, rides):
        self.route = route
        self.date = date
        self.daytype = daytype
        self.rides = rides

## A class with __slots__ is a memory - optimized class.
## It avoids using an instance dictionary, which saves memory.

## Define a regular class for rides data
class RegularRideRecord:
    def __init__(self, route, date, daytype, rides):
        self.route = route
        self.date = date
        self.daytype = daytype
        self.rides = rides

## A regular class is an object - oriented way to represent data.
## It has named attributes and can have methods.

## Function to read data as tuples
def read_as_tuples(filename):
    records = []
    with open(filename) as f:
        rows = csv.reader(f)
        next(rows)  ## Skip headers
        for row in rows:
            record = (row[0], row[1], row[2], int(row[3]))
            records.append(record)
    return records

## This function reads data from a CSV file and stores it as tuples.
## Tuples are immutable sequences, and you access their elements by numeric index.

## Function to read data as dictionaries
def read_as_dicts(filename):
    records = []
    with open(filename) as f:
        rows = csv.reader(f)
        headers = next(rows)  ## Get headers
        for row in rows:
            record = {
                'route': row[0],
                'date': row[1],
                'daytype': row[2],
                'rides': int(row[3])
            }
            records.append(record)
    return records

## This function reads data from a CSV file and stores it as dictionaries.
## Dictionaries use key - value pairs, so you can access elements by their names.

## Function to read data as named tuples
def read_as_named_tuples(filename):
    records = []
    with open(filename) as f:
        rows = csv.reader(f)
        next(rows)  ## Skip headers
        for row in rows:
            record = RideRecord(row[0], row[1], row[2], int(row[3]))
            records.append(record)
    return records

## This function reads data from a CSV file and stores it as named tuples.
## Named tuples combine the efficiency of tuples with the readability of named access.

## Function to read data as regular class instances
def read_as_regular_classes(filename):
    records = []
    with open(filename) as f:
        rows = csv.reader(f)
        next(rows)  ## Skip headers
        for row in rows:
            record = RegularRideRecord(row[0], row[1], row[2], int(row[3]))
            records.append(record)
    return records

## This function reads data from a CSV file and stores it as instances of a regular class.
## Regular classes allow you to add methods to your data.

## Function to read data as slotted class instances
def read_as_slotted_classes(filename):
    records = []
    with open(filename) as f:
        rows = csv.reader(f)
        next(rows)  ## Skip headers
        for row in rows:
            record = SlottedRideRecord(row[0], row[1], row[2], int(row[3]))
            records.append(record)
    return records

## This function reads data from a CSV file and stores it as instances of a slotted class.
## Slotted classes are memory - optimized and still provide named access.

## Function to measure memory usage
def measure_memory(func, filename):
    tracemalloc.start()

    records = func(filename)

    current, peak = tracemalloc.get_traced_memory()

    ## Demonstrate how to use each data structure
    first_record = records[0]
    if func.__name__ == 'read_as_tuples':
        route, date, daytype, rides = first_record
    elif func.__name__ == 'read_as_dicts':
        route = first_record['route']
        date = first_record['date']
        daytype = first_record['daytype']
        rides = first_record['rides']
    else:  ## named tuples and classes
        route = first_record.route
        date = first_record.date
        daytype = first_record.daytype
        rides = first_record.rides

    print(f"Structure type: {func.__name__}")
    print(f"Record count: {len(records)}")
    print(f"Example access: Route={route}, Date={date}, Rides={rides}")
    print(f"Current memory: {current/1024/1024:.2f} MB")
    print(f"Peak memory: {peak/1024/1024:.2f} MB")
    print("-" * 50)

    tracemalloc.stop()

    return current

if __name__ == "__main__":
    filename = '/home/labex/project/ctabus.csv'

    ## Run all memory tests
    print("Memory usage comparison for different data structures:\n")

    results = []
    for reader_func in [
        read_as_tuples,
        read_as_dicts,
        read_as_named_tuples,
        read_as_regular_classes,
        read_as_slotted_classes
    ]:
        memory = measure_memory(reader_func, filename)
        results.append((reader_func.__name__, memory))

    ## Sort by memory usage (lowest first)
    results.sort(key=lambda x: x[1])

    print("\nRanking by memory efficiency (most efficient first):")
    for i, (name, memory) in enumerate(results, 1):
        print(f"{i}. {name}: {memory/1024/1024:.2f} MB")

Exécutez le script pour voir les résultats de la comparaison :

python3 /home/labex/project/compare_structures.py

La sortie affichera l'utilisation mémoire de chaque structure de données, ainsi qu'un classement de la plus à la moins efficace en termes de mémoire.

Compréhension des différentes structures de données

  1. Tuples :

    • Les tuples sont des séquences légères et immuables. Cela signifie qu'une fois que vous avez créé un tuple, vous ne pouvez pas modifier ses éléments.
    • Vous accédez aux éléments d'un tuple par leur index numérique, comme record[0], record[1], etc.
    • Ils sont très efficaces en termes de mémoire car ils ont une structure simple.
    • Cependant, ils peuvent être moins lisibles car vous devez vous souvenir de l'index de chaque élément.
  2. Dictionnaires :

    • Les dictionnaires utilisent des paires clé - valeur, ce qui vous permet d'accéder aux éléments par leur nom.
    • Ils sont plus lisibles, par exemple, vous pouvez utiliser record['route'], record['date'], etc.
    • Ils ont une utilisation mémoire plus élevée en raison du surcoût de la table de hachage utilisée pour stocker les paires clé - valeur.
    • Ils sont flexibles car vous pouvez facilement ajouter ou supprimer des champs.
  3. Tuples nommés :

    • Les tuples nommés combinent l'efficacité des tuples avec la capacité d'accéder aux éléments par nom.
    • Vous pouvez accéder aux éléments en utilisant la notation pointée, comme record.route, record.date, etc.
    • Ils sont immuables, tout comme les tuples ordinaires.
    • Ils sont plus efficaces en termes de mémoire que les dictionnaires.
  4. Classes ordinaires :

    • Les classes ordinaires suivent une approche orientée objet et ont des attributs nommés.
    • Vous pouvez accéder aux attributs en utilisant la notation pointée, comme record.route, record.date, etc.
    • Vous pouvez ajouter des méthodes à une classe ordinaire pour définir un comportement.
    • Elles utilisent plus de mémoire car chaque instance a un dictionnaire d'instance pour stocker ses attributs.
  5. Classes avec __slots__ :

    • Les classes avec __slots__ sont des classes optimisées en termes de mémoire. Elles évitent d'utiliser un dictionnaire d'instance, ce qui économise de la mémoire.
    • Elles offrent toujours un accès nommé aux attributs, comme record.route, record.date, etc.
    • Elles limitent l'ajout de nouveaux attributs après la création de l'objet.
    • Elles sont plus efficaces en termes de mémoire que les classes ordinaires.

Quand utiliser chaque approche

  • Tuples : Utilisez les tuples lorsque la mémoire est un facteur critique et que vous n'avez besoin que d'un accès indexé simple à vos données.
  • Dictionnaires : Utilisez les dictionnaires lorsque vous avez besoin de flexibilité, par exemple, lorsque les champs de vos données peuvent varier.
  • Tuples nommés : Utilisez les tuples nommés lorsque vous avez besoin à la fois de lisibilité et d'efficacité mémoire.
  • Classes ordinaires : Utilisez les classes ordinaires lorsque vous avez besoin d'ajouter un comportement (méthodes) à vos données.
  • Classes avec __slots__ : Utilisez les classes avec __slots__ lorsque vous avez besoin de comportement et de l'efficacité mémoire maximale.

En choisissant la bonne structure de données pour vos besoins, vous pouvez améliorer considérablement les performances et l'utilisation mémoire de vos programmes Python, en particulier lorsque vous travaillez avec de grands ensembles de données.

✨ Vérifier la solution et pratiquer

Résumé

Dans ce laboratoire (lab), vous avez appris différentes manières de représenter des enregistrements en Python et analysé leur efficacité mémoire. Tout d'abord, vous avez compris la structure de base d'un ensemble de données CSV et comparé les méthodes de stockage de texte brut. Ensuite, vous avez travaillé avec des données structurées en utilisant des tuples et implémenté cinq différentes structures de données : les tuples, les dictionnaires, les tuples nommés, les classes ordinaires et les classes avec __slots__.

Les principaux points à retenir sont que les différentes structures de données offrent des compromis entre l'efficacité mémoire, la lisibilité et la fonctionnalité. La surcharge des objets Python a un impact significatif sur l'utilisation mémoire pour les grands ensembles de données, et le choix de la structure de données peut grandement affecter la consommation mémoire. Les tuples nommés et les classes avec __slots__ sont de bons compromis entre l'efficacité mémoire et la lisibilité du code. Ces concepts sont précieux pour les développeurs Python dans le traitement des données, en particulier lorsqu'ils manipulent de grands ensembles de données où l'efficacité mémoire est cruciale.