PYTHON - 由于list.pop()调用''for'索引更改

时间:2013-06-18 13:22:05

标签: python for-loop indexing pop

我有这个python代码,一个接一个地面对整数列表中的项目(在发布的代码中名为'see')与另一个列表的.f字段中的所有项目(名为'maxx'in代码已发布)。 在每次迭代中,我都计算(通过“c”变量)第j个项目出现在“maxx”列表中的次数,如果它出现的次数少于三次,我想从列表中弹出() 。 代码工作正常,但是弹出一个项目会将“看到”列表中的任何后续项目拉回一个位置,因此每次if条件满足时,循环都会错过列表的下一个项目。 我想不出办法解决这个问题,有什么想法吗?

感谢。

以下是代码:

for indj,j in enumerate(seen):    # every item in the 'seen' list..
    c=0
    for k in maxx:                # ..checks for a matching item in the 'maxx' list
        if j==k.f:
            c=c+1;
    if c<3:                       # if the item appears less than 3 times we pop it
        seen.pop(indj)

编辑:忘了说我试图添加

indj=indj-1
j=seen[indj]

在if结构的末尾,但它不起作用

2 个答案:

答案 0 :(得分:2)

您必须制作新列表或使用副本。当您在循环时更改列表时,您会跳过一些项目。我这样做:

def filter_low(lst, maxk, threshold=3):
    for item in lst:
        c = sum(1 for k in maxx if item==k.f)
        if c >= threshold:
             yield item


new_seen = list(filter_low(seen, maxk, 3))

与以下内容相同:

new_seen = [item for item in seen 
            if sum(1 for k in maxx if item==k.f) >= 3]

您可以通过执行

更改原始列表
seen[:] = [item for item in seen 
           if sum(1 for k in maxx if item==k.f) >= 3]

答案 1 :(得分:1)

修改你正在迭代的列表绝不是一个好主意。您可以迭代副本并使用

修改实际列表
popped = 0
for indj, j in enumerate(seen[:]):  
    s = sum(j == k.f for k in maxx)
    if s < 3:
        seen.pop(indj - popped)
        popped += 1

如果seen列表非常大,则可能效率低下。