我正在尝试计算Python中2组的交集,我想将一定范围内的值(+/- 5)视为相等。例如:
set1 = [22, 570, 233, 127, 92]
set2 = [897, 27, 673, 231, 45]
我想要的是:
len[x for x in set1 if x in set2] == 2
交叉口是22& 27以及233& 231。
有没有一种有效的方法呢?
答案 0 :(得分:1)
如果“有效”,则表示“短”,当然。
>>> set1 = [22, 570, 233, 127, 92]
>>> set2 = [897, 27, 673, 231, 45]
>>> len([x for x in set1 if any(abs(x-y) <= 5 for y in set2)])
2
如果“有效”意味着“有一个合理的大O运行时间”,那就不那么容易了。上述方法是O(N ^ 2)。你可以得到O(N * log(N))如果你对两个集合进行排序并且并行迭代它们寻找近似匹配,但这并不是完全无关紧要的。
[编辑 - 删除了用于OP输入的O(N log N)代码,但没有用于set1 = [1,3,4]和set2 = [2,10]]
答案 1 :(得分:0)
以记忆为代价,对于小范围(你的例子说+ -5),你可以为检查做更大的set
。
from itertools import chain
set1 = {22, 570, 233, 127, 92}
set2 = {897, 27, 673, 231, 45}
# Make a frozenset of all values considered overlapping with set2
overlap = 5
overlaprange = range(-overlap, overlap+1)
match2 = frozenset(chain.from_iterable((x + i for i in overlaprange) for x in set2))
print(len(set1 & match2))
这不会多次计算单个元素,如果set2
中的值靠得很近,则不会多次存储它们的重叠(转换为frozenset
match2
} uniquifies)。如果其中一个set
与其他几个set
匹配,您可以将重用的set
转换为“匹配set
”,然后将其用于每次交叉检查结束。