切片列表的 Pythonic 方式 w.r.t。元组中的第一个元素

Pythonic way of slicing a list w.r.t. first element in tuple

我有一个已排序的元组列表,形式为

x = 
[(0,1), (0,2), (0,3), ... 
 (1,1), (1,3), (1,4), ...
 ...
 (n,0), (n,4), ...
]

我想对列表进行切片,以便所有 (x,y) 的数字(其中 x 是新列表中的某个值)和顺序保持不变。现在,这显然可行:

y = [(a,b) for (a,b) in x if a == n]

但是真的很慢。用二分查找找到第一个和最后一个满足这个条件的索引会更快。 index 为您提供值的第一个索引,而反向列表的 index 将提供最后一个索引。如果不以 pythonic 方式执行 [a for (a,b) in x] 和复制整个列表,将如何应用它?

正如@Liongold 在评论中所建议的那样,您可以使用 bisect。假设您想要所有元组 tt[0] == 1:

from bisect import bisect_left

x = [(0, 1), (0, 2), (1, 1), (1, 2), (2, 1), (2, 2)]

start = bisect_left(x, (1, None))  # index of the very first (1, i) 
end = bisect_left(x, (2, None))  # index after the very last (1, i)

y = x[start:end]

# y: [(1, 1), (1, 2)]

您可以在 bisect docs 中找到详细信息。