在Python中,确定数字的最快方法是在彼此的特定范围内?

时间:2015-07-30 00:00:05

标签: python

我有以下数字列表 -

L = [ 1430185458, 1430185456, 1430185245, 1430185246, 1430185001 ]

我正在尝试确定哪些数字在" 2"范围内?彼此。列表将在我收到时未分类。

如果有2个范围内的数字,我必须返回" 1"收到完全相同的位置号码。

我能够达到预期的效果,但代码运行速度非常慢。我的方法涉及排序列表,使用两个指针迭代它并连续比较它。我将有数百万条记录作为单独的列表出现。

试着看看解决这个问题的最佳方法是什么。

编辑 - 道歉,因为我离开了一段时间。 List中可以包含任意数量的元素,范围从1到n。想法是在收到完全相同的位置编号时返回0或1。我无法发布我实现的实际代码,但这里是伪代码。

一个。创建新列表作为列表列表,第二部分为每个元素为0。我们假设在彼此的范围内没有数字。

    [[1430185458,0], [1430185456,0], [1430185245,0], [1430185246,0], [1430185001,0]]

湾排序原始列表

℃。比较第一个元素到第二个,第二个到第三个,依此类推,直到达到列表末尾,并且当差值小于或等于2时,在步骤a到1中更新相应的第二个元素。

    [[1430185458,1], [1430185456,1], [1430185245,1], [1430185246,1], [1430185001,0]]

2 个答案:

答案 0 :(得分:2)

目标是快速,因此可能意味着O(N)算法。构建NxN差异矩阵是O(N ^ 2),因此根本不好。排序是O(N * log(N)),因此也是如此。假设字典插入和查找的平均情况O(1)行为,以下是O(N)算法。它会在几秒钟内通过一百万个随机整数列表。

def in_range (numbers) :
    result = [0] * len(numbers)
    index = {}
    for idx, number in enumerate(numbers) :
        for offset in range(-2,3) :
            match_idx = index.get(number+offset)
            if match_idx is not None :
                result[match_idx] = result[idx] = 1 
        index[number] = idx 
    return result


更新

  

我必须返回" 1"收到完全相同的位置号码。

如果输入[[1,1],[2,1],[5,0]],问题的更新会要求提供[1,2,5]表单的列表。我没那样做。相反,我的代码会返回给定[1,1,0]的{​​{1}}。与[1,2,5]列表相比,生成简单的0/1列表的速度提高了约15%。可以使用[[value,in_range],...]

轻松创建所需列表
zip

答案 1 :(得分:0)

我认为这可以满足您的需求(process()修改列表L)。但很可能它仍然是可以优化的:

def process(L):
    s = [(v,k) for k,v in enumerate(L)]

    s.sort()

    j = 0
    for i,v_k in enumerate(s):
        v = v_k[0]

        while j < i and v-s[j][0]>2:
            j += 1

        while j < i:
            L[s[j][1]] = 1
            L[s[i][1]] = 1
            j += 1