如果我有数百万个项目的大型列表,我想迭代它们中的每一个。一旦我使用该项目,它将永远不会再次使用,所以我如何删除列表中的项目一旦使用?什么是最好的方法?我知道numpy快速而有效但想知道如何使用普通列表来完成它。
mylst = [item1, item2,............millions of items]
for each_item in mylist:
#use the item
#delete the item to free that memory
您无法直接在Python中删除对象 - 当无法再引用该对象时,通过垃圾回收自动回收对象的内存。只要对象在列表中,就可以稍后再次引用(通过列表)。
所以你也需要销毁这个列表。例如,像这样:
while mylst:
each_item = mylst.pop() # removes an object from the end of the list
# use the item
假设您可以复制列表(内存约束可能会导致问题)并且只需要从中删除特定元素,您可以创建列表的浅表副本,并在迭代原始列表时从中删除元素:
a_list = [1, 2, 3, 4, 5]
b_list = a_list.copy()
removal_key = 0
for element in a_list:
if element % 2 == 0:
b_list.pop(removal_key)
removal_key -= 1; # we need to push the removal key back afer every deletion as our array b_list becomes smaller than the original after every deletion
removal_key += 1
print(b_list) #[1, 3, 5]
如果创建第二个列表不是一个选项,则可以存储要从列表中删除的元素的键,然后使用第二个列表将其删除:
a_list = [1, 2, 3, 4, 5]
elements_to_remove = []
for key, element in enumerate(a_list):
if element % 2 == 0:
elements_to_remove.append(key)
removed_emelent_count = 0
for element in elements_to_remove:
a_list.pop(element - removed_emelent_count)
removed_emelent_count += 1
print(a_list) #[1, 3, 5]
请注意,第一种解决方案更节省时间(特别是在删除大量元素时),而第二种解决方案更节省内存,尤其是从列表中删除少量元素时。
这可能就是你应该使用generators的情况。
生成器是一个函数,它返回一个我们可以迭代的对象,一次一个值,使用特殊关键字yield
而不是return
。它们允许您通过每次迭代仅保留一个元素来减少内存占用。
在python3.x中,range
实际上是一个生成器(python2.x是xrange
)。
过于简单的例子:
>>> def range(start, end):
... current = start
... while current < end:
... yield current
... current += 1
...
>>> for i in range(0, 2):
... print(i)
...
0
1
这百万条目清单是如何制作的?