我在Python中迭代一个元组列表,并试图删除它们,如果它们满足某些条件。

for tup in somelist:
    if determine(tup):
         code_to_remove_tup

我应该用什么来代替code_to_remove_tup?我不知道怎么用这种方式把东西拿掉。


当前回答

for循环将遍历一个索引…

假设你有一个清单,

[5, 7, 13, 29, 65, 91]

您使用了一个名为lis的列表变量。你用同样的方法来移除…

你的变量

lis = [5, 7, 13, 29, 35, 65, 91]
       0  1   2   3   4   5   6

在第5次迭代中,

你的数字35不是质数,所以你把它从列表中删除了。

lis.remove(y)

然后下一个值(65)移动到前一个索引。

lis = [5, 7, 13, 29, 65, 91]
       0  1   2   3   4   5

所以第四次迭代完成指针移动到第五次…

这就是为什么你的循环没有覆盖65,因为它已经移动到前一个索引。

因此,你不应该将一个列表引用到另一个变量中,它仍然引用原始变量而不是副本。

ite = lis # Don’t do it will reference instead copy

所以使用list[::]复制列表。

现在你会付出,

[5, 7, 13, 29]

问题是你在迭代过程中从列表中删除了一个值,然后你的列表索引就会崩溃。

所以你可以试试列表理解。

它支持所有的可迭代对象,如list, tuple, dict, string等。

其他回答

我需要用一个巨大的列表来做这件事,复制列表似乎很昂贵,特别是因为在我的情况下,删除的数量与保留的项目相比很少。我采用了这种低层次的方法。

array = [lots of stuff]
arraySize = len(array)
i = 0
while i < arraySize:
    if someTest(array[i]):
        del array[i]
        arraySize -= 1
    else:
        i += 1

我不知道的是,与复制一个大列表相比,几个删除操作的效率有多高。如果你有什么见解,请评论。

我能想到三种方法来解决你的问题。例如,我将创建元组somelist =[(1,2,3),(4,5,6),(3,6,6),(7,8,9),(15,0,0),(10,11,12)]的随机列表。我选择的条件是元组元素之和= 15。在最终的列表中,我们将只有那些和不等于15的元组。

我所选择的是一个随机选择的例子。请随意更改元组列表和我所选择的条件。

方法1。使用你建议的框架(在for循环中填充代码)。我使用一个带del的小代码来删除满足上述条件的元组。然而,如果两个连续放置的元组满足给定条件,该方法将错过一个元组(满足上述条件)。

for tup in somelist:
    if ( sum(tup)==15 ): 
        del somelist[somelist.index(tup)]

print somelist
>>> [(1, 2, 3), (3, 6, 6), (7, 8, 9), (10, 11, 12)]

方法2。构造一个新的列表,其中包含不满足给定条件的元素(元组)(这与删除满足给定条件的列表元素是一样的)。下面是它的代码:

newlist1 = [somelist[tup] for tup in range(len(somelist)) if(sum(somelist[tup])!=15)]

print newlist1
>>>[(1, 2, 3), (7, 8, 9), (10, 11, 12)]

方法3。找到满足给定条件的索引,然后使用与这些索引对应的删除元素(元组)。下面是它的代码。

indices = [i for i in range(len(somelist)) if(sum(somelist[i])==15)]
newlist2 = [tup for j, tup in enumerate(somelist) if j not in indices]

print newlist2
>>>[(1, 2, 3), (7, 8, 9), (10, 11, 12)]

方法1和方法2比方法3快。方法2和方法3比方法1更有效。我更喜欢方法2。对于上面的例子,time(method1): time(method2): time(method3) = 1:1: 1.7

如果稍后将使用新列表,可以简单地将elem设置为None,然后在后面的循环中判断它,如下所示

for i in li:
    i = None

for elem in li:
    if elem is None:
        continue

这样,你就不需要复制列表,而且更容易理解。

for循环将遍历一个索引…

假设你有一个清单,

[5, 7, 13, 29, 65, 91]

您使用了一个名为lis的列表变量。你用同样的方法来移除…

你的变量

lis = [5, 7, 13, 29, 35, 65, 91]
       0  1   2   3   4   5   6

在第5次迭代中,

你的数字35不是质数,所以你把它从列表中删除了。

lis.remove(y)

然后下一个值(65)移动到前一个索引。

lis = [5, 7, 13, 29, 65, 91]
       0  1   2   3   4   5

所以第四次迭代完成指针移动到第五次…

这就是为什么你的循环没有覆盖65,因为它已经移动到前一个索引。

因此,你不应该将一个列表引用到另一个变量中,它仍然引用原始变量而不是副本。

ite = lis # Don’t do it will reference instead copy

所以使用list[::]复制列表。

现在你会付出,

[5, 7, 13, 29]

问题是你在迭代过程中从列表中删除了一个值,然后你的列表索引就会崩溃。

所以你可以试试列表理解。

它支持所有的可迭代对象,如list, tuple, dict, string等。

这里的大多数答案都要求您创建列表的副本。我有一个用例,其中列表相当长(110K项),明智的做法是继续减少列表。

首先,你需要用while循环替换foreach循环,

i = 0
while i < len(somelist):
    if determine(somelist[i]):
         del somelist[i]
    else:
        i += 1

i的值在if块中没有改变,因为一旦旧项被删除,您将希望从SAME INDEX中获得新项的值。