我有已经排序的列表。
我经常需要查看
if foo in sortedlist:
pass # not really. but not the point.
有没有办法教'in',sortlist是排序的,它应该二进制搜索列表?
答案 0 :(得分:4)
Python支持显式过度隐式。如果您知道数据已排序,则可以选择显式使用bisect
module,或者使用该模块创建实现list
的{{1}}子类。
例如:
__contains__
可以用作import bisect
class SortedList(list):
def __contains__(self, elem):
idx = bisect.bisect_left(self, elem)
return idx < len(self) and self[idx] == elem
的替代,list
会自动使用in
。您可能希望覆盖__contains__
,__setitem__
和.extend()
以按排序顺序维护列表。
答案 1 :(得分:2)
我的建议是将列表子类化为使用排序列表:
from bisect import bisect_left
class SortedList(list):
def __init__(self, l):
list.__init__(self, sorted(l))
def __contains__(self, obj):
pos = bisect_left(self, obj, 0, len(self))
return (pos != len(self) and self[pos] == obj)
然后:
>>> l = SortedList([4,3,5435,123,54,2,343,23])
>>> l
[2, 3, 4, 23, 54, 123, 343, 5435]
>>> 23 in l
True
>>> 25 in l
False
>>> 123122 in l
False
>>> -1 in l
False