python-3.x - 有没有更快的方法从 Python 3 中的列表中删除成员?
问题描述
我有一个定义为类的对象列表,例如:
class Foo:
def __init__(self,value):
self.v = value
我的列表包含大约 1e6 个这些对象,我经常在这样的 while 循环中删除其中一些:
from random import randrange
#Number of elements
N = 1000000
# Let's construct the list
Foos_list = []
for i in range(N):
Foos_list.append(Foo(i))
# Now let's remove members one by one
while len(Foos_list) > 0:
i_random = randrange(N)
Foos_list.remove(Foos_list[i_random])
我使用随机生成器来选择在每次迭代中应该删除哪个元素,因为在我的真实情况下,我对成员的访问有些随机或稀疏Foos_list
,我不确定这是否对我看到的缓慢有任何贡献。事实上,上面的代码可以正常工作,N ~ 200000
但之后它变得很慢。与相比,有没有更好的方法可以更有效地从类对象列表中删除元素remove
?
解决方案
list.remove(list[i])
是多余的,因为list.remove()
需要在列表中搜索list[i]
(这是 O(n)),但当然,它在i
. 改为使用del
。
while foos_list:
i_random = randrange(len(foos_list))
del foos_list[i_random]
现在,del
仍然是 O(n),所以你不会看到巨大的速度提升,但它至少应该有所帮助——比 O(2n) 更好。
顺便说一句,我做了三个修复:
- 避免使用 Upper_snake_case变量名。使用snake_case代替简单变量。
- 使用
if list
代替if len(list) > 0
- 在某些时候,
i_random
会大于len(foos_list)
因为N
大于len(foos_list)
第一次迭代之后。
为了进一步加快速度,我们需要更多的上下文。例如,也许您可以先对列表进行洗牌,然后.pop()
在每次迭代时简单地洗牌,但这取决于您对列表所做的事情。
推荐阅读
- javascript - Azure 存储 Javascript 库“createBlobServiceWithSas”引发错误:拒绝设置不安全的标头“用户代理”
- r - 减少一棵树的节点数,以获得具有多个子节点的节点
- sql - SQL Where 查询字符串中的列值
- python - 通过应用动态地将列添加到数据框
- mysql - 如何在一列中选择具有相同值但在另一列中彼此之间必须不同的行
- php - [Dialogflow]通过 Webhook 格式更新权限(用于推送通知)
- macos - 读取 DICOM 并使用 matplotlib 绘图时,没有可用的图像处理程序可以解码此传输语法 JPEG Lossless
- r - 如何使用 lubridate 转移到日期时间?
- android - 需要使用自定义适配器和上下文菜单从列表视图中获取项目
- javascript - 当我控制台日志时,我得到“w.fn.init [prevObject: w.fn.init(1)]”