我有两个很长的列表,我试图将第一个列表中的每个整数映射到最大阈值差异内的其他列表中的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
答案 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}
现在,C
对B
中的每个元素都有最接近的元素A
,但可能存在重复项(例如40
)。要解决这些问题,我们必须进行第二次传递,将A
中的元素按其&#34; closeness&#34;进行排序。使用B
来自C
的任何元素。然后,我们可以remove
B
将A
中的元素分配给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