2010-08-02 84 views

回答

7

如果row是一个列表,那么不要忘记,删除一个列表元素会将所有后续元素移回一个位置以填补空缺,因此所有较晚进入列表的索引都将被忽略, (每次删除另一个元素时,每个索引中的错误会增加一个)。有几种方法来避免这个问题 - 给一个,尝试向后遍历列表。

要回应如何向后迭代,您可以尝试使用可传递给range的额外参数。前两个参数给出的范围内遍历(下界是包容性的,和上限独家),第三个参数是步骤:

>>> range(5) 
[0, 1, 2, 3, 4] 
>>> range(0, 5) 
[0, 1, 2, 3, 4] 
>>> range(3, 5) 
[3, 4] 
>>> range(3, 5, -1) 
[] 
>>> range(5, 3, -1) 
[5, 4] 

所以,你的情况,似乎你想:

range(len(row) - 1, -1, -1) 

还是更容易阅读(感谢viraptor):

reversed(range(len(row)) 

或者,你可以尝试使用列表理解(我假设c是一个列表):

for row_number, row in enumerate(c): 
    c[row_number] = [x for i, x in enumerate(row) if i in keep] 
+0

我该如何向后迭代? – 2010-08-03 00:02:56

+2

for i in inverted(range(...)): – viraptor 2010-08-03 00:05:31

2

该索引存在于循环的开始处,但是一旦删除了一个元素,该列表就会变短,并且不包含相同数量的元素。因此,你的指数可能是错的。如果您从列表末尾删除,则不会使列表索引无效。

但我对这种模式感到惊讶;也许有更好的方法来解决你在找什么?也许设置减法或类似的东西会做你想做的事情,而不用修改列表几十或几百次。

3

也许你可以把它写这样

for row in c: 
    row[:] = [x for i,x in enumerate(row) if i in keep] 
+0

这并不具有完全相同的效果,因为列表理解会创建一个新列表,但不会将新列表保存回c。 – 2010-08-03 00:18:02

+0

@迈克尔,没问题,我通过做一个切片分配来解决它 – 2010-08-03 00:34:21

3

,而你是迭代,以防止这样的错误,不应更改列表。