web-dev-qa-db-fra.com

Ajout d'éléments à une liste de listes dans python

Je deviens fou avec les index de liste et je ne peux pas expliquer ce que je fais mal.

J'ai ce morceau de code dans lequel je veux créer une liste de listes, chacune contenant des valeurs du même paramètre de circuit (tension, courant, etc.) que je lis dans un fichier csv qui ressemble comme ça:

Sample, V1, I1, V2, I2
0, 3, 0.01, 3, 0.02
1, 3, 0.01, 3, 0.03

Etc. Ce que je veux, c'est créer une liste qui contient par exemple V1 et I1 (mais je veux choisir interactivement) sous la forme [[V1], [I1]], donc:

[[3,3], [0.01, 0.01]]

Le code que j'utilise est le suivant:

plot_data = [[]]*len(positions)    
for row in reader:
    for place in range(len(positions)):
        value = float(row[positions[place]])
        plot_data[place].append(value)

plot_data est la liste qui contient toutes les valeurs, tandis que positions est une liste avec les index des colonnes que je veux copier à partir du .csv fichier. Le problème est que si j'essaie les commandes dans le shell, semble fonctionner, mais si j'exécute le script au lieu d'ajouter chaque valeur à la sous-liste appropriée, il ajoute toutes les valeurs à toutes les listes, donc j'obtiens 2 (ou plus ) listes identiques.

45
clabacchio

Les listes Python sont des objets mutables et ici:

plot_data = [[]] * len(positions) 

vous répétez la même liste len(positions) fois.

>>> plot_data = [[]] * 3
>>> plot_data
[[], [], []]
>>> plot_data[0].append(1)
>>> plot_data
[[1], [1], [1]]
>>> 

Chaque liste de votre liste est une référence au même objet. Vous en modifiez un, vous voyez la modification dans chacun d'eux.

Si vous souhaitez des listes différentes, vous pouvez procéder comme suit:

plot_data = [[] for _ in positions]

par exemple:

>>> pd = [[] for _ in range(3)]
>>> pd
[[], [], []]
>>> pd[0].append(1)
>>> pd
[[1], [], []]
89
joaquin
import csv
cols = [' V1', ' I1'] # define your columns here, check the spaces!
data = [[] for col in cols] # this creates a list of **different** lists, not a list of pointers to the same list like you did in [[]]*len(positions) 
with open('data.csv', 'r') as f:
    for rec in csv.DictReader(f):
        for l, col in Zip(data, cols):
            l.append(float(rec[col]))
print data

# [[3.0, 3.0], [0.01, 0.01]]
2
eumiro