在长排序列表中搜索值之前和之后

时间:2011-07-08 18:25:29

标签: python

在长排序列表中搜索数字(例如12.31)的最快方法是什么,并且当找不到确切的值时,在我的“搜索”值之前和之后获取值(例如,11.12和12.03)在下面的列表中)?
非常感谢提前。

long_list = [10.11, 11.12, 13.03, 14.2 .. 12345.67]

4 个答案:

答案 0 :(得分:4)

最快的可能是在python中使用内置支持。在这里,我正在考虑bisect模块。下面我正在使用字典快速检查O(1)是否值在列表中;如果没有,bisect用于查找小于和大于所寻求值的值。

#!/usr/bin/env python

import bisect

def find_lt(a, x):
    'Find rightmost value less than x'
    i = bisect.bisect_left(a, x)
    if i:
        return a[i-1]
    raise ValueError

def find_gt(a, x):
    'Find leftmost value greater than x'
    i = bisect.bisect_right(a, x)
    if i != len(a):
        return a[i]
    raise ValueError

# First create a test-list (49996 items)
i=1.0
R=[1.0]
D={}
while i < 10000:
    i+=0.2
    i=round(i,2)
    D[i]=True
    R.append(i)

# Locate a value, in this case 100.3 which is not in the list
x=100.3
if D.has_key(x):
    print "found", x
else:
    print find_lt(R, x)
    print find_gt(R, x)

x=100.3的输出:

100.2
100.4

答案 1 :(得分:2)

如果列表非常长,则指数搜索(AKA驰骋搜索)将比纯二进制搜索执行得更好。这个想法是在增加的步骤中从位置0向前扫描,直到此时通过答案,可以执行二进制搜索到最后两个步骤形成的范围。如果未找到该元素,则最后一次尝试将指向最接近的元素。

看看Basic Techniques for information retrieval。提供了伪代码算法,并讨论了它对二进制搜索的复杂性。

答案 2 :(得分:0)

如果您的列表按照示例进行排序,我认为二进制搜索最快。

答案 3 :(得分:0)

li = [10.11, 11.12, 13.03, 14.2, 15.6, 15.8, 17.9, 12345.67]

def searsh(x,li):
    itli = iter(li)
    a = itli.next()
    if a==x:
        return a
    else:
        while True:
            b = itli.next()
            if b==x:
                return b
            elif a<x<b:
                return (a,b)
            a = itli.next()
            if a==x:
                return a
            elif b<x<a:
                return (b,a)


print searsh(13.5,li)
print searsh(10.11,li)
print searsh(50.3,li)
print searsh(12345.67,li)

结果

(13.03, 14.2)
10.11
(17.9, 12345.67)
12345.67

此外:

def searsh(x,li):
    a = li[0]
    if a==x:
        return a
    else:
        j = 0
        while True:
            j += 1
            b = li[j]
            if b==x:
                return b
            elif a<x<b:
                return (a,b)
            j += 1
            a = li[j]
            if a==x:
                return a
            elif b<x<a:
                return (b,a)