If you sort your list in the first step, you can make a much more efficient comparison and you can break the inner loop, when the first comparison fails. Because all next values will be even larger.
import itertools
import time
import numpy as np
from itertools import combinations, permutations
from math import isclose
def func1(lats):
pairs = []
lats_sorted = sorted(lats)
for index, lat1 in enumerate(lats_sorted[:-1]):
for lat2 in lats_sorted[index + 1:]:
if lat2 - lat1 <= 0.1:
pairs.append((lat1, lat2))
else:
break
return pairs
def func2(lats):
pairs = []
for i in lats:
for j in lats:
if (i - 0.1) <= j <= (i + 0.1):
pairs.append((i, j))
return pairs
def func3(lats):
pairs = []
for i, j in itertools.combinations(lats, 2):
if (i - 0.1) <= j <= (i + 0.1):
pairs.append((i, j))
return pairs
def func4(lats):
pairs = []
for i in lats:
for j in lats:
if (i - 0.1) <= j <= (i + 0.1) and i != j:
pairs.append((i, j))
return pairs
def func5(lats):
close_lats = [c for c in combinations(lats, 2) if abs(c[0] - c[1]) <= 0.1]
return close_lats
def func6(lats):
pairs = []
lats_sorted = sorted(lats)
i = 0
j = 1
while j < len(lats_sorted):
if lats_sorted[j] - lats_sorted[i] <= 0.1:
for lat in lats_sorted[i:j]:
pairs.append((lat, lats_sorted[j]))
j += 1
else:
i += 1
return pairs
def func7(lats):
pairs = []
for l1, l2 in permutations(lats, r=2):
if isclose(l1, l2, abs_tol=0.1):
pairs.append((l1, l2))
return pairs
lats = np.random.randint(0, 100000, 5000) / 1000
print(lats)
func_list = [func1, func2, func3, func4, func5, func6, func7]
for func in func_list:
start = time.time()
pairs = func(lats)
end = time.time()
print(f"{func.__name__}: time = {end - start} s, pair count = {len(pairs)}")
The output is
[94.644 79.527 29.458 ... 50.957 12.598 28.743]
func1: time = 0.03390932083129883 s, pair count = 24752
func2: time = 6.506390333175659 s, pair count = 54686
func3: time = 2.5684497356414795 s, pair count = 24843
func4: time = 6.778799533843994 s, pair count = 49408
func5: time = 3.18171763420105 s, pair count = 24752
func6: time = 0.007977962493896484 s, pair count = 24752
func7: time = 7.56172513961792 s, pair count = 49504
showing, that the proposed algorithm (func6) from Ali Moghaddaszadeh is way faster than the others. The slight count difference between func1/func6 and func3 (itertools solution) seems to be a numerical precision issue.