Home > Software engineering >  Find indexes of elements in list that is approximatly equal to element in another list
Find indexes of elements in list that is approximatly equal to element in another list

Time:05-27

I have 2 lists with floating point numbers:

list_1 = [1.03, 3.56, 4.91, 2.85, 5.55, 1.12, 1.73, 1.33, 2.56, 2.58, 3.53]
list_2 = [1.05, 1.55, 2.05, 2.55, 3, 3.55, 4]

The goal is to compare 2 lists and return the indexes of element from the first list (list_1) if they are approximatly equal based on the specific threshold.

def compare_lists(list1, list2, threshold=0.02):
    output_list = []
    for i in range(len(list1)):
        for j in range(len(list2)):
            print(abs(list1[i] - list2[j]))
            if abs(list1[i] - list2[j]) <= threshold:
                output_list.append(i)
    return output_list

This is only return [1, 8] that I think it is wrong. There are some indexes should be included in the output list such as 0 and the last one.

I think the problem is the subtraction of the floating points. I checked the difference between 1.03 and 1.05 and it returns 0.02000000000000018

How can I fix this problem? or I just could round them, but this is not a good choice because the list can contain varied decimal points. It doesn't scope just 2 points, as well as the threshold.

CodePudding user response:

You might want to have more padding, due to round-off error:

list_1 = [1.03, 3.56, 4.91, 2.85, 5.55, 1.12, 1.73, 1.33, 2.56, 2.58, 3.53]
list_2 = [1.05, 1.55, 2.05, 2.55, 3, 3.55, 4]

output = [i for i, x in enumerate(list_1) for y in list_2 if abs(x - y) <= 0.02   1e-8]
print(output) # [0, 1, 8, 10]

CodePudding user response:

Python has the decimal module https://docs.python.org/3/library/decimal.html "for fast correctly-rounded decimal floating point arithmetic".

from decimal import Decimal

list_1 = [1.03, 3.56, 4.91, 2.85, 5.55, 1.12, 1.73, 1.33, 2.56, 2.58, 3.53]
list_2 = [1.05, 1.55, 2.05, 2.55, 3, 3.55, 4]

def compare_lists(list1, list2, threshold=0.02):
    threshold = Decimal(str(threshold))
    list2 = [Decimal(str(y)) for y in list2]

    output_list = []
    for i, x in enumerate(list1):
        x = Decimal(str(x))
        if any(abs(x-y) <= threshold for y in list2):
            output_list.append(i)
    return output_list

print(compare_lists(list_1, list_2))  # prints [0, 1, 8, 10]
  • Related