找到两个列表之间的最大差异

时间:2012-02-17 05:02:25

标签: python algorithm data-structures ordereddictionary

我有两个列表oldnew,但元素数量相同。

我正在尝试编写一个有效的函数,它将n作为参数,比较相同位置的两个列表的元素(按索引),查找n最大差异,然后返回那些n元素的索引。

我认为这最好通过值排序字典解决,但Python中有一个isn't available(而且我不知道有任何提供它的库)。也许有更好的解决方案?

5 个答案:

答案 0 :(得分:9)

每当您想到“n largest”时,请考虑heapq

>>> import heapq
>>> import random
>>> l1 = [random.randrange(100) for _ in range(100)]
>>> l2 = [random.randrange(100) for _ in range(100)]
>>> heapq.nlargest(10, (((a - b), a, b) for a, b in zip(l1, l2)))
[(78, 99, 21), (75, 86, 11), (69, 90, 21), (69, 70, 1), (60, 86, 26), (55, 95, 40), (52, 56, 4), (48, 98, 50), (46, 80, 34), (44, 81, 37)]

这将在O(n log x)时间内找到x个最大的项目,其中n是列表中的项目总数;排序在O(n log n)时间内完成。

我突然意识到上述内容并没有真正按照你的要求行事。你想要一个索引!还是很容易的。如果你想要差异的绝对值,我也会在这里使用abs

>>> heapq.nlargest(10, xrange(len(l1)), key=lambda i: abs(l1[i] - l2[i]))
[91, 3, 14, 27, 46, 67, 59, 39, 65, 36]

答案 1 :(得分:2)

假设列表中的元素数量不是很大,您可以区分所有元素,排序并选择第一个n

print sorted((abs(x-y) for x,y in zip(old, new)), reverse=True)[:n]

这将是O(k log k),其中k是原始列表的长度。

如果n明显小于k,最好的办法是使用heapq模块提供的nlargest功能:

import heapq
print heapq.nlargest(n, (abs(x-y) for x,y in zip(old, new))

这将是O(k log n)而不是O(k log k),这对k >> n来说可能很重要。 此外,如果您的列表非常大,那么使用itertools.izip代替常规zip功能可能会更好。

答案 2 :(得分:0)

根据你的问题,我认为这就是你想要的:

在difference.py中

l1 = [15,2,123,4,50]
l2 = [9,8,7,6,5]


l3 = zip(l1, l2)

def f(n):
    diff_val = 0
    index_val = 0
    l4 = l3[:n]

    for x,y in l4:
        if diff_val < abs(x-y):
            diff_val = abs(x-y)
            elem = (x, y)
            index_val = l3.index(elem)

    print "largest diff: ", diff_val
    print "index of values:", index_val


n = input("Enter value of n:") 

f(n)

执行:

[avasal@avasal ]# python difference.py 
Enter value of n:4
largest diff:  116
index of values: 2
[avasal@avasal]#

如果这不是你想要的,请考虑再详述一下......

答案 3 :(得分:0)

>>> l = []
... for i in itertools.starmap(lambda x, y: abs(x-y), itertools.izip([1,2,3],   [100,102,330])):
...     l.append(i)
>>> l
5: [99, 100, 327]

itertools可用于重复性任务。从starmap转换tuples*args。对于referenceWith max功能,您将能够获得所需的结果。 index函数将有助于找到位置。

l.index(max(l)

>>> l.index(max(l))
6: 2

答案 4 :(得分:0)

这是numpy中一起被攻击的解决方案(免责声明,我是numpy的新手,因此可能有更简单的方法来执行此操作)。我没有结合任何步骤,所以很清楚每个步骤在做什么。最终值是最高增量顺序的原始列表的索引列表。挑选前n只是sorted_inds[:n],并且从每个列表或从增量列表中检索值都是微不足道的。

我不知道它在性能上与其他解决方案的比较,显然不会出现如此小的数据集,但是可能值得用你的真实数据集进行测试,因为我的理解是numpy是非常快速的数值运算。

代码

import numpy

list1 = numpy.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
list2 = numpy.array([9, 8, 7, 6, 5, 4, 3, 2, 1])

#Caculate the delta between the two lists
delta = numpy.abs(numpy.subtract(list1, list2))
print('Delta: '.ljust(20) + str(delta))

#Get a list of the indexes of the sorted order delta
sorted_ind = numpy.argsort(delta)
print('Sorted indexes: '.ljust(20) + str(sorted_ind))

#reverse sort
sorted_ind = sorted_ind[::-1]
print('Reverse sort: '.ljust(20) + str(sorted_ind))

输出

Delta:              [8 6 4 2 0 2 4 6 8]
Sorted indexes:     [4 3 5 2 6 1 7 0 8]
Reverse sort:       [8 0 7 1 6 2 5 3 4]