我在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?我不知道怎么用这种方式把东西拿掉。
当前回答
我需要做一些类似的事情,在我的情况下,问题是内存——我需要在一个列表中合并多个数据集对象,在对它们做了一些事情之后,作为一个新对象,并且需要摆脱我正在合并的每个条目,以避免重复所有它们并增加内存。在我的情况下,对象在一个字典而不是一个列表工作得很好:
```
k = range(5)
v = ['a','b','c','d','e']
d = {key:val for key,val in zip(k, v)}
print d
for i in range(5):
print d[i]
d.pop(i)
print d
```
其他回答
如果您想在迭代期间做其他事情,那么最好同时获得索引(这保证您能够引用它,例如,如果您有一个字典列表)和实际的列表项内容。
inlist = [{'field1':10, 'field2':20}, {'field1':30, 'field2':15}]
for idx, i in enumerate(inlist):
do some stuff with i['field1']
if somecondition:
xlist.append(idx)
for i in reversed(xlist): del inlist[i]
Enumerate使您可以同时访问项和索引。反向是为了以后你要删除的索引不会改变。
我能想到三种方法来解决你的问题。例如,我将创建元组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
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等。
for i in range(len(somelist) - 1, -1, -1):
if some_condition(somelist, i):
del somelist[i]
你需要向后走,否则就有点像锯掉你坐着的树枝:-)
Python 2用户:用xrange替换range以避免创建硬编码的列表
您需要获取列表的副本并首先对其进行迭代,否则迭代将失败,可能会出现意想不到的结果。
例如(取决于列表的类型):
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
[]