与此列表中的删除元素同时在同一列表上循环两次会导致未处理的元素



我正在寻找一种在同一时间与此列表中删除某些项目的同一列表中循环两次的方法。我注意到下面的代码在同一列表上循环两次与从此列表中删除元素的同一时间导致未处理的元素。

a=[1,3,1,9]
for i in a:
    print(i ,"element from the frist loop for")
    for j in a:
        if i==j:
            p=a.index(i)
            del a[p]
            print(a ,"list after removing element in the second loop for")

结果:

1 element from the frist loop for
[3, 1, 9] list after removing element in the second loop for
[3, 9] list after removing element in the second loop for
9 element from the frist loop for
[3] list after removing element in the second loop for

数字3没有处理,因为它不是从第一个循环

迭代的

在第一个循环中,我们从1到9跳。我想在第一个循环中处理3个。

我知道,在运行循环之前,默认情况下,使用循环循环列表的方式被冷冻。在示例中,列表A必须在索引0到3中进行遍历,因为列表中有4个数字,因此值3具有索引1。知道在第一个迭代中,我们删除了列表A的1个,值3否更长的索引1但0。但是,由于索引0已经扫描,因此跳过了值3。

在这里正确代码:

a=[object1,object3,object1,object9]
for i in a:
    print(i ,"element from the frist loop for")
    for j in a:
        if distance(i,j) == 0:
            p=a.index(i)
            del a[p]
            print(a ,"list after removing element in the second loop for")

我尝试删除两个元素,如果它们是近距离(欧几里得距离),否则我将它们保留在列表中。所有这些元素都在同一列表中,因此在同一列表上的双重循环

从列表中删除重复项的最简单方法是内置set()函数。在您的情况下:

list(set(a))

,如果您想使用循环,则可以创建一个新列表,而不是尝试修改您要迭代的列表。有多种更有效的方法可以做到这一点,但这是我的意思的简单示例:

a=[1,3,1,9]
b = []
for i in a:
    if i in b:
        continue
    else:
        b.append(i)

对于避免扫描每个项目的整个列表的更有效的方法,您可以从itertools文档中使用此食谱:

from itertools import filterfalse
def unique_everseen(iterable, key=None):
    seen = set()
    seen_add = seen.add
    if key is None:
        for element in filterfalse(seen.__contains__, iterable):
            seen_add(element)
            yield element
    else:
        for element in iterable:
            k = key(element)
            if k not in seen:
                seen_add(k)
                yield element

首先,您应该避免在其上进行觉得觉得。那可能很棘手。

我认为未处理该项目3,因为当您使用a.index()方法时,a的当前索引移至第二个1的位置,跳过3。

您可以通过创建新列表

来避免这种问题
a=[1,3,1,9]
a2 = list(a) # Or use `deepcopy` if your list contains other mutables like dict or lists
for p, i in enumerate(a):
    print(i ,"element from the frist loop for")
    for j in a:
        if i==j:
            del a2[p]
            print(a ,"list after removing element in the second loop for")

update

最终,您可以使用 lists classension 来简化此问题,例如:

a2 = [i for p, i in enumerate(a) if i > 0]

最新更新