Introduction
Cette section traite des listes, des dictionnaires et des ensembles.
Overview
Les programmes ont souvent besoin de travailler avec de nombreux objets.
- Un portefeuille d'actions
- Un tableau de prix d'actions
Il existe trois principaux choix à utiliser.
- Les listes. Données ordonnées.
- Les dictionnaires. Données non ordonnées.
- Les ensembles. Collection non ordonnée d'éléments uniques.
Les listes en tant que conteneur
Utilisez une liste lorsque l'ordre des données est important. Rappelez-vous que les listes peuvent contenir n'importe quel type d'objet. Par exemple, une liste de tuples.
portfolio = [
('GOOG', 100, 490.1),
('IBM', 50, 91.3),
('CAT', 150, 83.44)
]
portfolio[0] ## ('GOOG', 100, 490.1)
portfolio[2] ## ('CAT', 150, 83.44)
Construction de listes
Création d'une liste à partir de zéro.
records = [] ## Liste initialement vide
## Utilisez.append() pour ajouter plus d'éléments
records.append(('GOOG', 100, 490.10))
records.append(('IBM', 50, 91.3))
...
Un exemple lors de la lecture de records à partir d'un fichier.
records = [] ## Liste initialement vide
with open('portfolio.csv', 'rt') as f:
next(f) ## Passez l'en-tête
for line in f:
row = line.split(',')
records.append((row[0], int(row[1]), float(row[2])))
Les dictionnaires en tant que conteneur
Les dictionnaires sont utiles si vous voulez effectuer des recherches aléatoires rapides (par nom de clé). Par exemple, un dictionnaire de prix d'actions :
prices = {
'GOOG': 513.25,
'CAT': 87.22,
'IBM': 93.37,
'MSFT': 44.12
}
Voici quelques recherches simples :
>>> prices['IBM']
93.37
>>> prices['GOOG']
513.25
>>>
Construction de dictionnaires
Exemple de création d'un dictionnaire à partir de zéro.
prices = {} ## Dictionnaire initialement vide
## Insérez de nouveaux éléments
prices['GOOG'] = 513.25
prices['CAT'] = 87.22
prices['IBM'] = 93.37
Un exemple de remplissage du dictionnaire à partir du contenu d'un fichier.
prices = {} ## Dictionnaire initialement vide
with open('prices.csv', 'rt') as f:
for line in f:
row = line.split(',')
prices[row[0]] = float(row[1])
Remarque : Si vous essayez cela avec le fichier prices.csv, vous constaterez que cela fonctionne presque - il y a une ligne vide à la fin qui provoque une erreur. Vous devrez trouver un moyen de modifier le code pour prendre cela en compte (voir l'exercice 2.6).
Recherches dans les dictionnaires
Vous pouvez tester l'existence d'une clé.
if key in d:
## OUI
else:
## NON
Vous pouvez rechercher une valeur qui peut ne pas exister et fournir une valeur par défaut au cas où elle n'existerait pas.
name = d.get(key, default)
Un exemple :
>>> prices.get('IBM', 0.0)
93.37
>>> prices.get('SCOX', 0.0)
0.0
>>>
Clés composites
Presque tout type de valeur peut être utilisé comme clé d'un dictionnaire en Python. Une clé de dictionnaire doit être d'un type qui est immuable. Par exemple, des tuples :
holidays = {
(1, 1) : 'Jour de l'an',
(3, 14) : 'Jour de Pi',
(9, 13) : "Jour du programmeur",
}
Ensuite, pour accéder :
>>> holidays[3, 14]
'Jour de Pi'
>>>
Aucune liste, ensemble ni autre dictionnaire ne peut servir de clé de dictionnaire, car les listes et les dictionnaires sont mutables.
Ensembles
Les ensembles sont des collections d'éléments uniques et non triés.
tech_stocks = { 'IBM','AAPL','MSFT' }
## Syntaxe alternative
tech_stocks = set(['IBM', 'AAPL', 'MSFT'])
Les ensembles sont utiles pour les tests d'appartenance.
>>> tech_stocks
set(['AAPL', 'IBM', 'MSFT'])
>>> 'IBM' in tech_stocks
True
>>> 'FB' in tech_stocks
False
>>>
Les ensembles sont également utiles pour éliminer les doublons.
names = ['IBM', 'AAPL', 'GOOG', 'IBM', 'GOOG', 'YHOO']
unique = set(names)
## unique = set(['IBM', 'AAPL','GOOG','YHOO'])
Opérations supplémentaires sur les ensembles :
unique.add('CAT') ## Ajoute un élément
unique.remove('YHOO') ## Supprime un élément
s1 = { 'a', 'b', 'c'}
s2 = { 'c', 'd' }
s1 | s2 ## Union d'ensembles { 'a', 'b', 'c', 'd' }
s1 & s2 ## Intersection d'ensembles { 'c' }
s1 - s2 ## Différence d'ensembles { 'a', 'b' }
Dans ces exercices, vous commencez à construire l'un des principaux programmes utilisés pour le reste de ce cours. Effectuez votre travail dans le fichier report.py.
Exercice 2.4 : Une liste de tuples
Le fichier portfolio.csv contient une liste d'actions dans un portefeuille. Dans l'exercice 1.30, vous avez écrit une fonction portfolio_cost(filename) qui lisait ce fichier et effectuait un calcul simple.
Votre code aurait dû ressembler à ceci :
## pcost.py
import csv
def portfolio_cost(filename):
'''Calcule le coût total (nombre d'actions * prix) d'un fichier de portefeuille'''
total_cost = 0.0
with open(filename, 'rt') as f:
rows = csv.reader(f)
headers = next(rows)
for row in rows:
nshares = int(row[1])
price = float(row[2])
total_cost += nshares * price
return total_cost
En utilisant ce code comme guide, créez un nouveau fichier report.py. Dans ce fichier, définissez une fonction read_portfolio(filename) qui ouvre un fichier de portefeuille donné et le lit dans une liste de tuples. Pour ce faire, vous allez apporter quelques modifications mineures au code ci-dessus.
Tout d'abord, au lieu de définir total_cost = 0, vous allez créer une variable initialement définie comme une liste vide. Par exemple :
portfolio = []
Ensuite, au lieu de additionner le coût, vous allez transformer chaque ligne en tuple exactement comme vous l'avez fait dans l'exercice précédent et l'ajouter à cette liste. Par exemple :
for row in rows:
holding = (row[0], int(row[1]), float(row[2]))
portfolio.append(holding)
Enfin, vous retournerez la liste portfolio résultante.
Expérimentez votre fonction de manière interactive (un rappel : pour ce faire, vous devez d'abord exécuter le programme report.py dans l'interpréteur) :
Indice : Utilisez -i lors de l'exécution du fichier dans le terminal
>>> portfolio = read_portfolio('/home/labex/project/portfolio.csv')
>>> portfolio
[('AA', 100, 32.2), ('IBM', 50, 91.1), ('CAT', 150, 83.44), ('MSFT', 200, 51.23),
('GE', 95, 40.37), ('MSFT', 50, 65.1), ('IBM', 100, 70.44)]
>>>
>>> portfolio[0]
('AA', 100, 32.2)
>>> portfolio[1]
('IBM', 50, 91.1)
>>> portfolio[1][1]
50
>>> total = 0.0
>>> for s in portfolio:
total += s[1] * s[2]
>>> print(total)
44671.15
>>>
Cette liste de tuples que vous avez créée est très similaire à un tableau 2D. Par exemple, vous pouvez accéder à une colonne et une ligne spécifiques en utilisant une recherche telle que portfolio[row][column] où row et column sont des entiers.
Cela étant dit, vous pouvez également réécrire la dernière boucle for en utilisant une instruction comme celle-ci :
>>> total = 0.0
>>> for name, shares, price in portfolio:
total += shares*price
>>> print(total)
44671.15
>>>
Exercice 2.5 : Liste de dictionnaires
Prenez la fonction que vous avez écrite dans l'exercice 2.4 et modifiez-la pour représenter chaque action dans le portefeuille avec un dictionnaire au lieu d'un tuple. Dans ce dictionnaire, utilisez les noms de champs "name", "shares" et "price" pour représenter les différentes colonnes dans le fichier d'entrée.
Expérimentez cette nouvelle fonction de la même manière que vous l'avez fait dans l'exercice 2.4.
>>> portfolio = read_portfolio('/home/labex/project/portfolio.csv')
>>> portfolio
[{'name': 'AA','shares': 100, 'price': 32.2}, {'name': 'IBM','shares': 50, 'price': 91.1},
{'name': 'CAT','shares': 150, 'price': 83.44}, {'name': 'MSFT','shares': 200, 'price': 51.23},
{'name': 'GE','shares': 95, 'price': 40.37}, {'name': 'MSFT','shares': 50, 'price': 65.1},
{'name': 'IBM','shares': 100, 'price': 70.44}]
>>> portfolio[0]
{'name': 'AA','shares': 100, 'price': 32.2}
>>> portfolio[1]
{'name': 'IBM','shares': 50, 'price': 91.1}
>>> portfolio[1]['shares']
50
>>> total = 0.0
>>> for s in portfolio:
total += s['shares']*s['price']
>>> print(total)
44671.15
>>>
Ici, vous remarquerez que les différents champs pour chaque entrée sont accessibles par des noms de clés au lieu de numéros de colonne numériques. Cela est souvent préférable car le code résultant est plus facile à lire plus tard.
La visualisation de grands dictionnaires et de listes peut être embrouillante. Pour nettoyer la sortie pour le débogage, considérez utiliser la fonction pprint.
>>> from pprint import pprint
>>> pprint(portfolio)
[{'name': 'AA', 'price': 32.2,'shares': 100},
{'name': 'IBM', 'price': 91.1,'shares': 50},
{'name': 'CAT', 'price': 83.44,'shares': 150},
{'name': 'MSFT', 'price': 51.23,'shares': 200},
{'name': 'GE', 'price': 40.37,'shares': 95},
{'name': 'MSFT', 'price': 65.1,'shares': 50},
{'name': 'IBM', 'price': 70.44,'shares': 100}]
>>>
Exercice 2.6 : Dictionnaires comme conteneur
Un dictionnaire est un moyen pratique de suivre des éléments lorsque vous voulez rechercher des éléments en utilisant un index autre qu'un entier. Dans l'interpréteur Python, essayez de manipuler un dictionnaire :
>>> prices = { }
>>> prices['IBM'] = 92.45
>>> prices['MSFT'] = 45.12
>>> prices
... regardez le résultat...
>>> prices['IBM']
92.45
>>> prices['AAPL']
... regardez le résultat...
>>> 'AAPL' in prices
False
>>>
Le fichier prices.csv contient une série de lignes avec des prix d'actions. Le fichier ressemble à ceci :
"AA",9.22
"AXP",24.85
"BA",44.85
"BAC",11.27
"C",3.72
...
Écrivez une fonction read_prices(filename) qui lit un ensemble de prix comme celui-ci dans un dictionnaire où les clés du dictionnaire sont les noms d'actions et les valeurs dans le dictionnaire sont les prix d'actions.
Pour ce faire, commencez par un dictionnaire vide et commencez à insérer des valeurs dedans tout comme vous l'avez fait ci-dessus. Cependant, vous lisez maintenant les valeurs à partir d'un fichier.
Nous utiliserons cette structure de données pour rechercher rapidement le prix d'un nom d'action donné.
Plusieurs petits conseils que vous aurez besoin pour cette partie. Tout d'abord, assurez-vous d'utiliser le module csv tout comme vous l'avez fait auparavant - il n'est pas nécessaire de réinventer la roue ici.
>>> import csv
>>> f = open('/home/labex/project/prices.csv', 'r')
>>> rows = csv.reader(f)
>>> for row in rows:
print(row)
['AA', '9.22']
['AXP', '24.85']
...
[]
>>>
L'autre petite complication est que le fichier prices.csv peut avoir quelques lignes vides. Remarquez comment la dernière ligne de données ci-dessus est une liste vide - ce qui signifie qu'aucune donnée n'était présente sur cette ligne.
Il y a une possibilité que cela fasse planter votre programme avec une exception. Utilisez les instructions try et except pour le capturer en conséquence. Pensée : serait-il mieux de protéger contre les données invalides avec une instruction if au lieu de cela?
Une fois que vous avez écrit votre fonction read_prices(), testez-la de manière interactive pour vous assurer qu'elle fonctionne :
>>> prices = read_prices('/home/labex/project/prices.csv')
>>> prices['IBM']
106.28
>>> prices['MSFT']
20.89
>>>
Exercice 2.7 : Vérifier si vous pouvez prendre votre retraite
Reliez tout ce travail en ajoutant quelques instructions supplémentaires à votre programme report.py qui calcule le gain/perte. Ces instructions devraient prendre la liste d'actions de l'exercice 2.5 et le dictionnaire de prix de l'exercice 2.6 et calculer la valeur actuelle du portefeuille ainsi que le gain/perte.
Sommaire
Félicitations ! Vous avez terminé le laboratoire sur les conteneurs. Vous pouvez pratiquer d'autres laboratoires sur LabEx pour améliorer vos compétences.