遍历列表副本并进行删除时,为什么Python for循环会跳过元素?

时间:2018-10-16 23:59:39

标签: python list loops for-loop alias

我正在遍历一个列表,有时我从另一个列表中删除了一个元素。而不是从其他列表中删除该元素,for循环将跳过整个实际迭代。我找到了解决方案,但我不太了解。

这是一个代码示例。除了我在行final_dt_list.remove(dt)注释掉之外,它是两次相同的:

dt_list = [3600, 2700, 1800, 900]
final_dt_list = dt_list
for dt in dt_list:
    print(dt)
    if not((3600/dt).is_integer()):
        print('skipped '+str(dt))
        final_dt_list.remove(dt)
        continue
    print('ok')

print('\n \n')

dt_list = [3600, 2700, 1800, 900]
final_dt_list = dt_list
for dt in dt_list:
    print(dt)
    if not((3600/dt).is_integer()):
        print('skipped '+str(dt))
        #final_dt_list.remove(dt)
        continue
    print('ok')

我得到的结果是:

3600
ok
2700
skipped 2700
900
ok



3600
ok
2700
skipped 2700
1800
ok
900
ok

从第一个循环的结果中可以看到,没有打印1800,什么也没发生。

最后对我有用的是创建要删除的项目列表。然后创建一个新的循环来遍历我要删除的项目。然后,此新循环将从final_dt_list中删除每个元素。

在此处查看解决方案代码:

for r in removed:
    final_dt_list.remove(r)

为什么现在可以正常运行,而不是上面的示例?我很困惑。

谢谢!

1 个答案:

答案 0 :(得分:2)

dt_listfinal_dt_list指向同一对象(别名)。 您可以在循环浏览列表时编辑列表。由于只保留用于循环显示位置的指针,但由于元素消失而改变。

尝试通过以下方式重新标记要删除的元素:

    dt_list = [3600, 2700, 1800, 900]
    rm_list = []
    for dt in dt_list:
        print(dt)
        if not((3600/dt).is_integer()):
            print('skipped '+str(dt))
            rm_list.append(dt)
            continue
        print('ok')
    dt_list = [x for x in dt_list if x not in rm_list]

编辑:

从一开始就使用列表理解会导致:

dt_list = [3600, 2700, 1800, 900]
dt_list = [x for x in dt_list if (3600/x).is_integer()]