我正在过滤类似的元组
newtuple = filter(lambda x: x[2].startswith('902'), csvlist)
然后尝试将其从我的原始csvlist中删除
csvlist.remove(newtuple) //<--Gives error
但得到;
ValueError: list.remove(x): x not in list
我在这里做错了什么?
答案 0 :(得分:0)
适应我已确认的评论:filter
将所有匹配项作为一个序列返回,而不仅仅是第一个匹配项,因此“ newtuple
”在这里是用词不当,实际上是“ newtuples
”复数( Py2上list
个tuple
中的一个,Py3上tuple
s个的生成者)。
最直接的解决方法是将代码更改为:
newtuples = filter(lambda x: x[2].startswith('902'), csvlist)
for newtuple in newtuples: # in list(newtuples) on Py3 to avoid mutating csvlist while iterating
csvlist.remove(newtuple)
但是有一些问题;如前所述,您需要list
验证Py3上filter
的结果,从性能角度来看,它是O(n**2)
;每个remove
调用都是O(n)
,并且可以想象对csvlist
中的每个元素执行一个调用。
一种更高效,可移植且Pythonic的解决方案是使用list
理解来一次过滤输入,然后将csvlist
的内容替换为{{1 }}理解。总共只有list
个工作,listcomps可以避免O(n)
+ filter
的函数调用开销。改进的代码是:
lambda
这将生成新的csvlist[:] = [x for x in csvlist if x[2].startswith('902')]
,并删除所有不需要的元素,然后将list
的内容替换为原位置。如果没有对csvlist
的其他引用应进行更新,则可以删除切片分配以进行普通分配(csvlist
而不是csvlist = ...
),以提高性能。< / p>