2012-12-06 91 views
9

我有一个列表的列表,列表中的每个列表包含5个项目,我如何更改列表中的项目的值?我曾尝试以下:Python - 如何更改列表中的值?

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

本来我有一个元组列表,但我意识到我不能在一个元组发生变化值,所以我切换到列表中,但我仍然不能改变任何值。如果我在for循环中打印ctype,x,y,delay,myctype,myx,myy或mydelay,则表明所有内容都正常工作,但如果我以后打印execlist,则看到没有任何更改。

+0

'itemnumber's是唯一的吗?或者还有另一个原因,即使在完成替换之后,您仍然想遍历整个列表? –

回答

12

问题是您正在创建列表的副本,然后修改副本。你想要做的是修改原始列表。试试这个:

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

您需要通过索引进行分配。假设你有一个列表清单,其中每个内部列表都有5个项目,如你所描述的。如果你想通过他们迭代并改变每个内部列表中的第二项的值,你可以这样做:

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

可变拆包似乎并不通过参考,但复制的值。 的解决办法是做这样的:

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

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

print(foo) 

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

你可以使用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 

可以删除#如果execlist只包含至多一个子表,其第一项可以等于mynumber;否则,你将无用地遍历整个列表的其余部分。

而且如果itemnumbers其实都是独一无二的,你可能会更好用字典或至少一个OrderedDict,这取决于你打算用你的数据做什么。

0

不要在列表中分配局部变量。在循环

for i in lis: 
    i = 5 

只需将变量i 5和叶名单不变的实际内容。相反,你必须直接给它分配:

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

申请表的名单,虽然在这种情况下,本地变量没有被分配,所以你可以使用for...in构筑体的相同。

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

更改在for中分配的变量不会更改列表。这是一个相当可读的方式做你想要什么:

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 

输出:

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

,循环变量是原始的副本(Python没有参考这样的一个概念,虽然结构如列表通过参考引用)。你需要做的是这样的:

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

item本身是一个副本太多,但它是原来的嵌套列表的引用的副本,所以当你是指它的元素原来的名单进行更新。

这不方便,因为你没有名字;也许字典或类将是一个更方便的结构。