迭代时从列表中删除项目而不使用 Python 中的额外内存

2022-01-24 00:00:00 python list iteration

问题描述

我的问题很简单:我有一长串要遍历的元素,并根据条件检查每个元素.根据条件的结果,我想删除列表的当前元素,并像往常一样继续迭代它.

My problem is simple: I have a long list of elements that I want to iterate through and check every element against a condition. Depending on the outcome of the condition I would like to delete the current element of the list, and continue iterating over it as usual.

我已经阅读了一些关于这个问题的其他帖子.将提出两种解决方案.要么从列表中创建一个字典(这意味着对我的情况下已经填满所有 RAM 的所有数据进行复制).要么反向遍历列表(这打破了我想要实现的算法的概念).

I have read a few other threads on this matter. Two solutions seam to be proposed. Either make a dictionary out of the list (which implies making a copy of all the data that is already filling all the RAM in my case). Either walk the list in reverse (which breaks the concept of the alogrithm I want to implement).

还有比这更好或更优雅的方法吗?

Is there any better or more elegant way than this to do it ?

def walk_list(list_of_g):
    g_index = 0
    while g_index < len(list_of_g):
        g_current = list_of_g[g_index]
        if subtle_condition(g_current):
            list_of_g.pop(g_index)
        else:
            g_index = g_index + 1


解决方案

如果您绝对必须从原始列表中删除项目,并且您没有足够的内存来制作副本,这是一个替代答案 - 移动自己在列表中的项目:

Here is an alternative answer for if you absolutely have to remove the items from the original list, and you do not have enough memory to make a copy - move the items down the list yourself:

def walk_list(list_of_g):
    to_idx = 0
    for g_current in list_of_g:
        if not subtle_condition(g_current):
            list_of_g[to_idx] = g_current
            to_idx += 1
    del list_of_g[to_idx:]

这会将每个项目(实际上是指向每个项目的指针)移动一次,因此将是 O(N).函数末尾的 del 语句将删除列表末尾的所有不需要的项目,我认为 Python 足够智能,可以调整列表大小而无需为列表的新副本分配内存.

This will move each item (actually a pointer to each item) exactly once, so will be O(N). The del statement at the end of the function will remove any unwanted items at the end of the list, and I think Python is intelligent enough to resize the list without allocating memory for a new copy of the list.

相关文章