python - Python给出ValueError:list.remove(x):从列表中删除元组时x不在列表中
问题描述
我过滤了一个像这样的元组;
newtuple = filter(lambda x: x[2].startswith('902'), csvlist)
然后尝试从我原来的 csvlist 中删除它
csvlist.remove(newtuple) //<--Gives error
但是得到;
ValueError: list.remove(x): x not in list
我在这里做错了什么?
解决方案
改编我确认的评论:filter
将所有匹配项作为一个序列返回,而不仅仅是第一个匹配项,因此“ newtuple
”在这里是用词不当,它实际上是“ newtuples
”复数( Py2 上list
的tuple
s 的 a,Py3 上的 s 的生成器tuple
)。
最直接的解决方法是将代码更改为:
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)
但这有一些问题;如前所述,您需要确定Py3 上list
的结果,并且在性能方面,它是; 每个调用都是,并且您可以想象对.filter
O(n**2)
remove
O(n)
csvlist
一个更有效、更便携和 Pythonic 的解决方案是使用推导式list
在一次传递中过滤输入,然后用推导式csvlist
的结果替换 's 的内容list
。它只是O(n)
总工作量,listcomps 可以避免filter
+的函数调用开销lambda
。改进后的代码是:
csvlist[:] = [x for x in csvlist if x[2].startswith('902')]
这会生成新的list
,删除所有不需要的元素,然后替换csvlist
原地的内容。如果您没有任何其他csvlist
应更新的引用,则可以删除切片分配以进行普通分配(csvlist = ...
而不是csvlist[:] = ...
)以提高性能。
推荐阅读
- python - 如何在 OSX 上卸载所有 Python 2.7 包(不卸载 Python)?
- html - HTML5 视频标签是否有“异步”模式?
- python - Python:针对浮点数和字符串的输入验证
- python - Dockerized Django 应用程序拒绝连接
- python - 如何将列表中的元素用作 range() 中的参数?
- typescript - 打字稿:我可以定义一个 n 长度的元组类型吗?
- r - R data.table 条件连接列 [...] 在 x 中找不到
- r - 使用 dplyr 从其他数据帧创建一个新数据帧
- ruby-on-rails - ruby on rails - fixture_file_upload 不适用于 CarrierWave 的控制器测试
- bash - Bash 脚本获得权限被拒绝