如何检查一个列表是否是另一个列表的子集(有容差)
我正在尝试解决一个问题,该问题涉及确定一个列表是否是另一个列表的子集,除非有一个额外的转折,即即使值不完全匹配,代码也应将列表视为子集,只要它在一个公差范围内。
例子:
如果我有以下清单:
A = [0.202, 0.101]
B = [0.1, 0.2, 0.3, 0.4, 0.5]
并且我设置了容差tol = 0.002,那么代码应该返回该列表A是列表的子集,B因为它的值在容差范围内 ( 0.202 <= 0.2 + tol,0.101 <= 0.1 + tol ) 内。
我没有太多代码要显示,因为我知道如何使用传统issubset函数确定一个列表是否是另一个列表的子集,但我不确定如何将容差纳入其中。
回答
您可以执行以下操作(先使用伪代码):
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
但请注意,处理浮点数是危险的。根据这篇文章,我们可以使用该decimal模块进行比较。
转换为简单的 Python 代码:
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}")
现在更紧凑地使用生成器和函数:
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)
- I keep forgetting about for-else … thanks! the continue was supposed to break the outer for-loop, but ofc that doesn't work. TBH I'd always just use the generator version, so I probably didn't put enough effort in the other one …