根据值对列表进行切片

nit*_*tin 4 python list

我在 python 中有一个排序列表(没有重复),就像这样,

l = [1, 3, 5, 8, 9, 11, 13, 17]
Run Code Online (Sandbox Code Playgroud)

我想根据列表值分一杯羹。因此,如果感兴趣的值是 5。那么我想在列表中找到这个值,并在列表中获取它之前的 3 个值。

我可以通过以下功能达到我的目标

def f(k):
    if k in l:
        i = l.index(k)
        return (l[i-2:i+1])
    else:
        pass


print (f(5))

[1, 3, 5]


print (f(13))

[9, 11, 13]
Run Code Online (Sandbox Code Playgroud)

但是,我有两个问题。如果感兴趣的值不是列表成员,我不知道该怎么办。f(6) 也应该返回 [1,3,5]。我不知道如何在此列表中找到 6

有没有一些“pythonic”的方法来做到这一点

小智 6

您可以使用:

 less_values = [x for x in l if x < 5]
Run Code Online (Sandbox Code Playgroud)

这应该你给出一个所有值都小于 5 的新列表

在那里您可以轻松选择最后 3 个值


Jon*_*nts 5

我会尝试一下,由于列表已排序并且没有重复项,那么您应该使用某种形式的二分搜索。Python 有一个bisect模块作为标准库的一部分,非常方便。

代码

import bisect

data = [1, 3, 5, 6, 8, 9, 11, 13, 17]
for val in range(19):
    pos = bisect.bisect_right(data, val)
    print val, '->', data[max(0, pos-3):pos]
Run Code Online (Sandbox Code Playgroud)

输出

0 -> []
1 -> [1]
2 -> [1]
3 -> [1, 3]
4 -> [1, 3]
5 -> [1, 3, 5]
6 -> [3, 5, 6]
7 -> [3, 5, 6]
8 -> [5, 6, 8]
9 -> [6, 8, 9]
10 -> [6, 8, 9]
11 -> [8, 9, 11]
12 -> [8, 9, 11]
13 -> [9, 11, 13]
14 -> [9, 11, 13]
15 -> [9, 11, 13]
16 -> [9, 11, 13]
17 -> [11, 13, 17]
18 -> [11, 13, 17]
Run Code Online (Sandbox Code Playgroud)