Python大型列表(内部约1.5亿个列表,每个列表包含4个字符串元素)转换速度加快

Python大型列表(内部约1.5亿个列表,每个列表包含4个字符串元素)转换速度加快,python,performance,list,large-data,Python,Performance,List,Large Data,通过这段代码,我在处理大型列表时获得了很长的性能(超过24小时)(其中约有1.5亿个列表元素,每个元素有4个字符串元素)。我需要从中删除大约6600万个元组: def erase_random_elements(elements_list, iterable_random_numbers): for i in sorted(iterable_random_numbers, reverse = True): elements_list.pop(i) return e

通过这段代码,我在处理大型列表时获得了很长的性能(超过24小时)(其中约有1.5亿个列表元素,每个元素有4个字符串元素)。我需要从中删除大约6600万个元组:

def erase_random_elements(elements_list, iterable_random_numbers):
    for i in sorted(iterable_random_numbers, reverse = True):
        elements_list.pop(i)
    return elements_list
看来我已经有足够的内存了,所以我不需要在列表中分块。如何更快地执行此操作?

不要使用
list.pop(I)
,因为每次删除操作(链接页面上的删除项)都需要时间。因为您有足够的内存,所以可以创建一个新列表:

def erase_random_elements(elements_list, iterable_random_numbers):
    s = set(iterable_random_numbers)
    elements_list[:] = [x for i, x in enumerate(elements_list) if i not in s]
    #return elements_list -> not required actually because we're updating the list in-place
请注意,这里我使用了
elements\u list[:]
,因为在原始函数中,您正在更新实际的列表,而不是创建一个新的列表,这意味着对该列表的所有引用都将保持完整。但是如果不需要这样做,那么您可以简单地删除
[:]
,取消对返回行的注释,并将函数返回的列表分配给一个变量。

但是我还建议使用而不是内置的Python列表

下面的示例使用(使用另一个数组进行索引)以及

在IPython中使用
%timeit
比较两种解决方案(Ashwini的列表理解和上面的numpy方法),结果表明使用numpy要快很多(~100倍):


由于值是而不是falsy(元组),因此您可以执行以下操作

def erase_random_elements(elements_list, iterable_random_numbers):
    for i in iterable_random_numbers:
        elements_list[i] = None
    elements_list[:] = filter(None, elements_list)

什么是
iterable\u random\u numbers
?可以迭代的列表或生成器。我希望
b
在这里是一个集合(在LC版本中),但是我确信LC与NumPy相比仍然会很慢。@Ashwini是的,我将
a
转换为一个列表,将
b
转换为一个集合,以确保这是一个公平的测试:)在Python 3.4上,我得到的结果是,对于100000个列表和50000个索引(每秒),这比Ashwini的答案快约5倍。
In [28]: %timeit a2 = a[~b]
1000 loops, best of 3: 1.37 ms per loop
In [29]: %timeit a2 = [x for i, x in enumerate(a) if i not in b]
10 loops, best of 3: 170 ms per loop
def erase_random_elements(elements_list, iterable_random_numbers):
    for i in iterable_random_numbers:
        elements_list[i] = None
    elements_list[:] = filter(None, elements_list)