我在Python中迭代一个元组列表,并试图删除它们,如果它们满足某些条件。
for tup in somelist:
if determine(tup):
code_to_remove_tup
我应该用什么来代替code_to_remove_tup?我不知道怎么用这种方式把东西拿掉。
我在Python中迭代一个元组列表,并试图删除它们,如果它们满足某些条件。
for tup in somelist:
if determine(tup):
code_to_remove_tup
我应该用什么来代替code_to_remove_tup?我不知道怎么用这种方式把东西拿掉。
当前回答
对于任何有潜力做大的东西,我使用以下方法。
import numpy as np
orig_list = np.array([1, 2, 3, 4, 5, 100, 8, 13])
remove_me = [100, 1]
cleaned = np.delete(orig_list, remove_me)
print(cleaned)
这应该比其他任何东西都快得多。
其他回答
我能想到三种方法来解决你的问题。例如,我将创建元组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
建议列表推导的答案几乎是正确的,除了它们构建了一个全新的列表,然后给它一个与旧列表相同的名称,它们没有在适当的地方修改旧列表。这与Lennart建议的选择性删除不同——它更快,但如果您的列表是通过多个引用访问的,那么您只是重新设置了其中一个引用,而没有更改列表对象本身,这可能会导致微妙的、灾难性的错误。
幸运的是,它非常容易获得列表推导式的速度和所需的就地更改的语义——只是代码:
somelist[:] = [tup for tup in somelist if determine(tup)]
请注意与其他答案的细微区别:这个答案没有分配给一个裸名。它赋值给一个列表切片,恰好是整个列表,因此替换了同一Python列表对象中的列表内容,而不是像其他答案一样只是重新设置一个引用(从以前的列表对象到新的列表对象)。
您需要获取列表的副本并首先对其进行迭代,否则迭代将失败,可能会出现意想不到的结果。
例如(取决于列表的类型):
for tup in somelist[:]:
etc....
一个例子:
>>> somelist = range(10)
>>> for x in somelist:
... somelist.remove(x)
>>> somelist
[1, 3, 5, 7, 9]
>>> somelist = range(10)
>>> for x in somelist[:]:
... somelist.remove(x)
>>> somelist
[]
如果希望在迭代时从列表中删除元素,请使用while循环,以便在每次删除后都可以更改当前索引和结束索引。
例子:
i = 0
length = len(list1)
while i < length:
if condition:
list1.remove(list1[i])
i -= 1
length -= 1
i += 1
这里的大多数答案都要求您创建列表的副本。我有一个用例,其中列表相当长(110K项),明智的做法是继续减少列表。
首先,你需要用while循环替换foreach循环,
i = 0
while i < len(somelist):
if determine(somelist[i]):
del somelist[i]
else:
i += 1
i的值在if块中没有改变,因为一旦旧项被删除,您将希望从SAME INDEX中获得新项的值。