How to check if a list is a subset of another list (with tolerance)

Viewed 131

I'm trying to solve a problem that involves the figuring out if one list is a subset of another, except there is an added twist that the code should consider the list a subset even if the values don't completely match, as long as it's within a tolerance.

EXAMPLE:

If I have the lists:

A = [0.202, 0.101]
B = [0.1, 0.2, 0.3, 0.4, 0.5]

and I set a tolerance of tol = 0.002, then the code should return that list A is a subset of list B since its values are within the tolerance (0.202 <= 0.2 + tol, 0.101 <= 0.1 + tol).

I don't have much code to show since I know how to figure out if a list is a subset of another using the traditional issubset function, but I'm not sure how to incorporate the tolerance into it.

1 Answers

You could do the following (pseudo-code first):

For each elment a of A:
    for each element b of B:
        if a is close enough to b, consider a to be in B
    if a was not close enough to an element in B, break the loop as A is not a subset of B

But notice that dealing with floating point numbers is dangerous. According to this post, we can use the decimal module for the comparisons.

Translation to a simple Python code:

from decimal import Decimal

for a in A:
    for b in B:
        if abs(Decimal(str(a)) - Decimal(str(b))) <= tol:
            break
    else:
        print('A is not a subset of B')
        break
else:
    print(f"A is a subset of B with a tolerance of {tol}")

Now more compactly with generators and a function:

def tol_subset(A, B, tol):
    return all(any(abs(Decimal(str(a)) - Decimal(str(b))) <= tol for b in B) for a in A)
Related