9

Python中是否有任何预制的优化工具/库来剪切/切片列表以获取“小于”的值?

这是问题所在:假设我有一个类似的列表:

a=[1,3,5,7,9]

我想删除所有<=6 的数字,所以结果列表是

[7,9]

6 不在列表中,所以无法使用列表的内置index(6)方法。我可以做这样的事情:

#!/usr/bin/env python
a = [1, 3, 5, 7, 9]
cut=6
for i in range(len(a)-1, -2, -1):
    if a[i] <= cut:
        break
b = a[i+1:]
print "Cut list: %s" % b

如果要从中剪切的索引接近列表的末尾,这将是一种相当快速的方法,但是如果项目接近列表的开头(假设我想删除所有>2,会有很多次迭代)。

我也可以使用二进制搜索等实现我自己的 find 方法,但我想知道是否有一个更广泛的内置库来处理我可以在其他情况下重用的此类事物(例如,如果我需要删除所有的数字>=6)。

先感谢您。

4

5 回答 5

6

您可以使用bisect 模块执行排序搜索:

>>> import bisect
>>> a[bisect.bisect_left(a, 6):]
[7, 9]
于 2012-11-29T17:54:13.823 回答
5

bisect.bisect_left是你要找的,我猜。

于 2012-11-29T17:53:10.257 回答
3

如果您只想过滤满足特定条件的所有元素的列表,那么最直接的方法是使用内置filter函数。

这是一个例子:

a_list = [10,2,3,8,1,9]

# filter all elements smaller than 6:
filtered_list = filter(lambda x: x<6, a_list)

filtered_list遗嘱包含:

 [2, 3, 1]

注意:此方法不依赖于列表的排序,因此对于非常大的列表,可能为有序搜索优化的方法(如bisect)在速度方面表现更好。

于 2012-11-29T18:04:12.853 回答
2

二等分左右辅助函数

#!/usr/bin/env python3

import bisect

def get_slice(list_, left, right):
    return list_[
        bisect.bisect_left(list_, left):
        bisect.bisect_left(list_, right)
    ]

assert get_slice([0, 1, 1, 3, 4, 4, 5, 6], 1, 5) == [1, 1, 3, 4, 4]

在 Ubuntu 16.04、Python 3.5.2 中测试。

于 2017-11-24T17:12:03.283 回答
1

添加到乔恩的答案中,如果您需要实际删除小于 6 的元素并希望保留对列表的相同引用,而不是返回一个新的引用。

del a[:bisect.bisect_right(a,6)]

您还应该注意,这bisect仅适用于排序列表。

于 2012-11-29T18:05:03.370 回答