由于元组已排序,您可以简单地搜索值低于阈值的第一个元组,然后使用切片表示法删除剩余的值:
index = next(i for i, (t1, t2) in enumerate(myTup) if t2 < threshold)
del myTup[index:]
正如 Vaughn Cato 所指出的,二分搜索会加快速度。bisect.bisect
会很有用,除非您创建一个单独的键序列,否则它将不适用于您当前的数据结构,如此处所述。但这违反了您禁止创建新列表的规定。
不过,您可以使用源代码作为您自己的二进制搜索的基础。或者,您可以更改数据结构:
>>> myTup
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e'), (5, 'f'),
(6, 'g'), (7, 'h'), (8, 'i'), (9, 'j')]
>>> index = bisect.bisect(myTup, (threshold, None))
>>> del myTup[:index]
>>> myTup
[(6, 'g'), (7, 'h'), (8, 'i'), (9, 'j')]
这里的缺点是删除可能会在线性时间内发生,因为 Python 必须将整个内存块移回......除非 Python 很聪明地删除从0
. (有人知道吗?)
最后,如果你真的愿意改变你的数据结构,你可以这样做:
[(-9, 'a'), (-8, 'b'), (-7, 'c'), (-6, 'd'), (-5, 'e'), (-4, 'f'),
(-3, 'g'), (-2, 'h'), (-1, 'i'), (0, 'j')]
>>> index = bisect.bisect(myTup, (-threshold, None))
>>> del myTup[index:]
>>> myTup
[(-9, 'a'), (-8, 'b'), (-7, 'c'), (-6, 'd')]
(请注意,Python 3 会抱怨None
比较,所以你可以使用类似的东西(-threshold, chr(0))
。)
我怀疑我一开始建议的线性时间搜索在大多数情况下都是可以接受的。