如何在最短的时间内从两个列表中映射最接近的整数?

时间:2017-11-03 07:27:09

标签: python arrays list

我有两个很长的列表,我试图将第一个列表中的每个整数映射到最大阈值差异内的其他列表中的closet整数。我可以循环遍历整个列表但是有更快的方法吗?输出可以像x (of list A ) = y (of list B)。如果数字与两个整数等距,则可以选择任何一个。我尝试使用 -

from itertools import product
sorted(product(arr1, arr2), key=lambda t: abs(t[0]-t[1]))

非常慢,也不是一对一的映射。

示例:

输入

A = [1, 3, 8, 77, 66, 25, 40]
B= [2, 5, 12, 120, 30, 21, 40]
Threshold = 40

输出

1 = 2; 3 = 5; 8 = 12; 77-在最低限度之下辍学; 66 = 30(40越接近但在其他列表中有更好的匹配); 25 = 21; 40 = 40

3 个答案:

答案 0 :(得分:2)

让我们使用bisect.bisect_left(a, x, lo=0, hi=len(a))库,参考:https://docs.python.org/3.6/library/bisect.html

  

from bisect import bisect_left, bisect_right A = [1, 3, 8, 4, 77, 66, 25, 40] B = [2, 5, 12, 120, 30, 21, 40] Threshold = 40 B.sort() for k in A: left = bisect_left(B, k) right = bisect_right(B, k) s = B[left] if abs(B[left] - k) < abs(B[right] - k) else B[right] if abs(k - s) <= Threshold: print(k, s)

     

在a中找到x的插入点以维护排序顺序。

示例:

ssh

答案 1 :(得分:1)

您可以使用二进制搜索在 O(n log n)中执行此操作。在Python中,您可以使用bisect模块。

import bisect

A = [1, 3, 8, 77, 66, 25, 40]
B = [2, 5, 12, 120, 30, 21, 40]
threshold = 40

B = sorted(B)  # has to be sorted for binary search

def closest(a, B):
    i = bisect.bisect(B, a)
    b = min(B[max(0, i-1):i+1], key=lambda b: abs(a - b))
    if abs(a - b) < threshold:
        return b

C = {a: closest(a, B) for a in A}
C = {a: b for a, b in C.items() if b is not None}
print(C)  # {1: 2, 66: 40, 3: 2, 40: 40, 8: 5, 25: 21, 77: 40}

现在,CB中的每个元素都有最接近的元素A,但可能存在重复项(例如40)。要解决这些问题,我们必须进行第二次传递,将A中的元素按其&#34; closeness&#34;进行排序。使用B来自C的任何元素。然后,我们可以remove BA中的元素分配给D = {} for a in sorted(C, key = lambda a: abs(C[a] - a)): b = closest(a, B) if b: D[a] = b B.remove(b) print(D) # {1: 2, 66: 30, 3: 5, 8: 12, 40: 40, 25: 21} 中的某个元素。{/ p>

this._image.src = url;

答案 2 :(得分:0)

如果您愿意,可以尝试:

print(" ".join(["{}={}".format(i[0],i[1]) for i in list(zip(A,B)) if abs(i[0] - i[1]) <= 30]))

输出:

1=2 3=5 8=12 25=21 40=40