根据 python(和任何公共库)中的函数从列表中删除项目的最有效方法是什么?
例如,如果我有以下功能:
def func(a):
return a % 2 == 1
以及以下列表:
arr = [1,4,5,8,20,24]
然后我想要结果:
new_arr = [1,5]
我知道我可以像这样简单地遍历列表:
new_arr = [i for i in arr if func(a)]
只是想知道这是否是一种有效的方法(对于大型数据集),或者是否有更好的方法。我在想也许使用 np 来映射并更改函数以返回 if True 和 -1 if false,然后使用 np remove 删除所有 0?
编辑: 我决定根据大家给出的建议自己测试它(我可能只是应该自己测试运行时而不是偷懒去问其他人)。
filter
是迄今为止最快的。不过,如果您需要一个随机访问列表,它可以与 [i for i in arr if func(i)]
方法相媲美。
numpy [np.vectorize(func)(arr)]
比其他列表方法稍快。
答案 0 :(得分:2)
这是内置 filter
函数的用例:
filtered_arr = filter(func, arr)
注意这返回一个迭代器,而不是一个列表。如果你想要一个列表,你可以用 list(filtered_arr)
或你提到的列表理解来创建一个。但是,如果您只想迭代过滤后的项目并且不需要随机访问/索引,则使用迭代器的内存效率更高。
对于过滤不是特别大并且包含任意(可能是混合)类型的元素的列表,这是一种很好的通用方法。如果您正在处理大量数值数据,则应使用其他答案中提到的 NumPy 解决方案之一。
答案 1 :(得分:0)
既然存在 numpy 标签,就让我们使用它。在示例中,我们对除以 2 时余数为 1 的元素使用掩码。
>>> import numpy as np
>>>
>>> arr = np.array([1,4,5,8,20,24])
>>> arr
array([ 1, 4, 5, 8, 20, 24])
>>> arr[arr % 2 == 1]
array([1, 5])
答案 2 :(得分:0)
使用 numpy,您可以使用 numpy.vectorize
将函数映射到数组元素,然后使用它来保留计算结果为 True
的元素。所以从你的功能开始
def func(a):
return a % 2 == 1
我们可以测试只保留 [0, 19] 范围内的奇数值
>>> import numpy as np
>>> arr = np.arange(20)
>>> arr
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
>>> np.vectorize(func)(arr)
array([False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True])
>>> arr[np.vectorize(func)(arr)]
array([ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19])
答案 3 :(得分:0)
您也可以重写 func
以使其接受列表作为参数:
def func(lst):
lst = [x for x in lst if x % 2 == 1]
return lst
然后做:
new_arr = func(arr)
与使 func
将单个数字作为参数并在每次要在列表(的元素)上使用它时编写一个迭代(例如 [for i in arr if func(a)]
)相比,这将为您节省一些行。
答案 4 :(得分:0)
我决定根据大家给出的建议自己测试它(我可能只是应该自己测试运行时而不是偷懒并询问其他人)。
filter
是迄今为止最快的。不过,如果您需要一个随机访问列表,它可以与 [i for i in arr if func(i)]
方法相媲美。
numpy [np.vectorize(func)(arr)]
比其他方法稍快。
只是想张贴这个以防将来有人遇到这个问题。