基于函数从列表中删除项目

时间:2021-06-10 17:47:43

标签: python numpy

根据 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)] 比其他列表方法稍快。

5 个答案:

答案 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)] 比其他方法稍快。

只是想张贴这个以防将来有人遇到这个问题。

相关问题