После того, как вы решили проблему для двух списков, вы можете использовать ее итеративно, начиная с первых двух, затем объедините список 1 и список 2 и выполните проверку между объединенными списками и списком 3, затем объедините список 3 с этим и обработать объединенный список со списком 4 и т. д.
Сравнение logi c между двумя списками может быть значительно ускорено путем сортировки подсписок в list1 и использования bisect_left для поиска первого элемента 'b', который является > = до a-20, затем последовательно продвигайтесь по отсортированным элементам, пока не достигнете значения +20. Вы можете сделать это для каждого элемента «a» в соответствующем подсписке списка 2. Это даст вам временную сложность O (NlogM) вместо O (N * M), что станет еще более важным, когда вы объедините списки в многосписковый процесс.
Вот конкретный пример процесса с несколькими списками.
Обратите внимание, что я не включил оптимизацию поиска пополам в функцию matchSubLists (это может потребоваться только в том случае, если ваши подсписки достаточно велики)
def matchSubLists(sA,sB,match):
return [ (a,b) for b in sB for a in sA if match(a,b) ]
def match2Lists(A,B,match):
return [ matchSubLists(sA,sB,match) for sA,sB in zip(A,B)]
def merge2Lists(A,B):
return [ sA+sB for sA,sB in zip(A,B) ]
def matchMultiLists(*L,match):
result = [[] for _ in L[0]]
merged = L[0]
for Ln in L[1:]:
matches = match2Lists(merged,Ln,match)
result = merge2Lists(result,matches)
merged = merge2Lists(merged,Ln)
return result
output:
l1 = [[80,112,270], [20,78], [6], [99,134,240,300]]
l2 = [[30], [22,84], [7,122,189,279], [67,100]]
l3 = [[60], [25, 70], [2], [110]]
result = matchMultiLists(l1,l2,l3, match=lambda a,b:abs(a-b)<=20)
print(result)
[
[(80, 60)],
[(20, 22), (78, 84), (20, 25), (22, 25), (78, 70), (84, 70)],
[(6, 7), (6, 2), (7, 2)],
[(99, 100), (99, 110), (100, 110)]
]
Я использовал подсписки с одной записью вместо значений int, чтобы работать с более согласованной структурой данных и избежать ненужных исключений в логах c
[EDIT]
Если вы хотите, чтобы выходные данные были одинаковыми независимо от порядка списков в вызове matchMultiList, вы можете добавить сортировку перед возвратом результата:
def matchMultiLists(*L,match):
result = [[] for _ in L[0]]
merged = L[0]
for Ln in L[1:]:
matches = match2Lists(merged,Ln,match)
result = merge2Lists(result,matches)
merged = merge2Lists(merged,Ln)
# consistently ordered result (2-level sort)
result = [ sorted( map(tuple,map(sorted,sR)) ) for sR in result ]
return result
Поскольку вы можете использовать matchMultiLists с двумя списками, вам не нужно добавлять сортировку в функцию match2Lists (). Фактически, 3 однострочные функции могут быть определены внутри функции matchMultiLists (), чтобы избежать их раскрытия.
output:
l1=[[96, 110], [49, 95, 122], [173, 218], [30], [80, 159], [95, 119, 150, 168]]
l2=[[25, 110], [63, 126], [130, 222], [42], [3], [94, 119, 150, 176]]
range20 = lambda a,b:abs(a-b)<=20
print(matchMultiLists(l1,l2, match=range20))
[[(96, 110), (110, 110)], [(49, 63), (122, 126)], [(218, 222)], [(30, 42)], [], [(94, 95), (119, 119), (150, 150), (150, 168), (168, 176)]]
print(matchMultiLists(l2,l1, match=range20))
[[(96, 110), (110, 110)], [(49, 63), (122, 126)], [(218, 222)], [(30, 42)], [], [(94, 95), (119, 119), (150, 150), (150, 168), (168, 176)]]