2012-12-06 4 views
9

J'ai une liste de listes, chaque liste dans la liste contient 5 éléments, comment puis-je changer les valeurs des éléments de la liste? Je l'ai essayé ce qui suit:Python - Comment changer les valeurs dans une liste de listes?

for [itemnumber, ctype, x, y, delay] in execlist: 
     if itemnumber == mynumber: 
      ctype = myctype 
      x = myx 
      y = myy 
      delay = mydelay 

Au départ, j'avais une liste de tuples, mais je réalise que je ne peux pas changer les valeurs dans un tuple si je suis passé à la liste, mais je ne peux pas changer encore l'une des valeurs. Si j'imprime ctype, x, y, delay, myctype, myx, myy ou mydelay à partir de la boucle for, il semble que tout fonctionne mais si j'imprime execlist par la suite, je vois que rien n'a changé.

+0

Est-ce que 'itemnumber's est unique? Ou y a-t-il une autre raison pour laquelle vous voulez parcourir toute la liste, même après un remplacement? –

Répondre

12

Le problème est que vous créez une copie de la liste, puis que vous modifiez la copie. Ce que vous voulez faire est de modifier la liste originale. Essayez ceci à la place:

for i in range(len(execlist)): 
    if execlist[i][0] == mynumber: 
     execlist[i][1] = myctype 
     execlist[i][2] = myx 
     execlist[i][3] = myy 
     execlist[i][4] = mydelay 
2

Vous devez affecter via des index. Disons que vous avez une liste de listes, où les listes internes ont chacune 5 éléments comme vous le décrivez. Si vous voulez itérer et les changer dans chaque liste intérieure la valeur du deuxième élément, vous pouvez faire quelque chose comme:

l = [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14]] 
for i in l: 
    i[1] = "spam" 

print l 
(output) [[0, "spam", 2, 3, 4], [5, "spam", 7, 8, 9], [10, "spam", 12, 13, 14]] 
0

décompactage variable ne semble pas passer la référence mais copie les valeurs. Une solution serait de le faire comme ceci:

foo = [[1, "gggg"], [3, "zzzz"]] 

for item in foo: 
    item[0] = 2 
    item[1] = "ffff" 

print(foo) 

>>>> [[2, 'ffff'], [2, 'ffff']] 
2

Vous pouvez utiliser enumerate():

for index, sublist in enumerate(execlist): 
    if sublist[0] == mynumber: 
     execlist[index][1] = myctype 
     execlist[index][2] = myx 
     execlist[index][3] = myy 
     execlist[index][4] = mydelay 
     # break 

Vous pouvez retirer le # si execlist ne contient que au plus un sous-liste dont le premier élément peut égaler mynumber; Sinon, vous parcourrez inutilement tout le reste de la liste. Et si le itemnumbers est en fait unique, il vaudrait peut-être mieux utiliser un dictionnaire ou au moins un OrderedDict, en fonction de ce que vous avez l'intention de faire avec vos données.

0

N'attribuez pas de variables locales dans les listes. Dans la boucle

for i in lis: 
    i = 5 

définit seulement la variable i-5 et laisse le contenu réel de la liste inchangée. Au lieu de cela, vous devez assigner directement:

for i in range(len(lis)): 
    lis[i] = 5 

est de même pour les listes de listes, bien que dans ce cas, la variable locale ne doit pas être affecté de sorte que vous pouvez utiliser la for...in construction.

for i in listoflists: 
    for i2 in range(len(i)): 
      i[i2] = 5 #sets all items in all lists to 5 
0

Modification des variables affectées dans le for ne change pas la liste. Voici une façon assez lisible pour faire ce que vous voulez:

execlist = [ 
    #itemnumber, ctype, x, y, delay 
    [1, 2, 3, 4, 5], 
    [6, 7, 8, 9, 10], 
    [11, 12, 13, 14, 15], 
] 

mynumber, myctype, myx, myy, mydelay = 6, 100, 101, 102, 104 

for i, sublist in enumerate(execlist): 
    if sublist[0] == mynumber: 
     execlist[i] = [mynumber, myctype, myx, myy, mydelay] 

print execlist 

Sortie:

[[1, 2, 3, 4, 5], [6, 100, 101, 102, 104], [11, 12, 13, 14, 15]] 
0

Les variables iterator sont des copies de l'original (Python ne dispose pas d'un concept de référence en tant que tel, bien que des structures telles que les listes sont référencées par référence).Vous devez faire quelque chose comme:

for item in execlist: 
    if item[0] == mynumber: 
     item[1] = ctype 
     item[2] = myx 
     item[3] = myy 
     item[4] = mydelay 

item lui-même est une copie aussi, mais il est une copie d'une référence à la liste imbriquée originale, donc quand vous faites référence à ses éléments la liste initiale est mis à jour.

Ce n'est pas aussi pratique puisque vous n'avez pas les noms; peut-être qu'un dictionnaire ou une classe serait une structure plus pratique.

Questions connexes