我有一个定义为类的对象列表,如下所示:
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()
,但这取决于您对列表执行的操作。