我有两个列表old
和new
,具有相同数量的元素。
我正在尝试编写一个有效的函数,它n
以参数为参数,比较相同位置的两个列表的元素(按索引),找到n
最大的差异,并返回这些n
元素的索引。
我在想这最好通过按值排序的字典来解决,但是Python中没有这个字典(而且我不知道有任何提供它的库)。也许有更好的解决方案?
我有两个列表old
和new
,具有相同数量的元素。
我正在尝试编写一个有效的函数,它n
以参数为参数,比较相同位置的两个列表的元素(按索引),找到n
最大的差异,并返回这些n
元素的索引。
我在想这最好通过按值排序的字典来解决,但是Python中没有这个字典(而且我不知道有任何提供它的库)。也许有更好的解决方案?
>>> 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]
假设列表中的元素数量不大,您可以将它们全部区别,排序并选择第一个n
:
print sorted((abs(x-y) for x,y in zip(old, new)), reverse=True)[:n]
这将是O(k log k)
您k
原始列表的长度。
如果n
明显小于k
,最好使用模块nlargest
提供的函数heapq
:
import heapq
print heapq.nlargest(n, (abs(x-y) for x,y in zip(old, new))
这将O(k log n)
代替O(k log k)
which 可能对k >> n
. itertools.izip
此外,如果您的列表真的很大,那么使用而不是常规zip
功能可能会更好。
根据您的问题,我认为这就是您想要的:
在差异.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]#
如果这不是您想要的,请考虑再详细说明这个问题..
>>> 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
. 供参考。With max
功能,您将能够得到想要的结果。index
功能将有助于找到位置。
l.index(max(l)
>>> l.index(max(l))
6: 2
这是一个用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]