在 python 的元组中查找重叠数字
Finding overlapping numbers in a tuple in python
我正在做一个 NLP 项目,我有一个列表,其中包含一些文本中的字符跨度。
此列表可能如下所示:
[(1,4),(1,7),(4,9),(8,15)]
所以我的任务是 return 所有非重叠对。
如果两个或多个数字对重叠,则跨度最长的对应该 returned。在我的示例中,我想要 return [(1,7),(8,15)]
。我该怎么做?
编辑
我不想像 那样合并我的间隔。但我不想 return 所有 pairs/intervals/tuples 除非某些元组中的值重叠。例如(1,4) 和 (1,7) 重叠, (4,9) 与 (1,4) 和 (1,7) 重叠。如果有一些重叠,我想 return 具有最大跨度的元组,例如(1,7) = 跨度 7,(1,4) = 跨度 4,(4,9) = 跨度 5。这意味着它也应该 return (1,7) 和 (8,15)因为 (8,15) 不重叠 (1,7)
还没想太多,但下面的方法应该可以解决问题:
spans = [(1,4),(1,7),(4,9),(8,15)]
del_in = []
for x in spans:
if spans.index(x) in del_in: continue
for y in spans:
if spans.index(y) in del_in: continue
if x == y: continue
if len(set(list(range(x[0],x[1]+1))) & set(list(range(y[0],y[1]+1)))) > 0:
if len(list(range(x[0],x[1]+1))) > len(list(range(y[0],y[1]+1))):
del_in.append(spans.index(y))
spans.pop(spans.index(y))
elif len(list(range(y[0],y[1]+1))) > len(list(range(x[0],x[1]+1))):
del_in.append(spans.index(x))
spans.pop(spans.index(x))
print(spans)
会输出:
[(1, 7), (8, 15)]
简短说明:
我们开始遍历跨度列表(迭代 x
)。对于每个元组,我们再次遍历列表(迭代 y
),忽略来自 x
(if x == y: continue
) 的元组。然后,我们将每个元组转换为一个列表(例如 (1,4)
到 [1, 2, 3, 4]
)和 list(range())
并比较列表(尽可能与 set()
)以查看它们是否有任何元素常见的。如果返回对象的长度大于 0,我们比较两个列表的长度,看我们保留哪一个(跨度较大的那个)。随后,我们从列表中删除跨度较小的项目(.pop()
)。由于我们的迭代 x
和 y
仍然通过我们的初始列表,我们需要实施一种机制来防止脚本将项目与已删除的条目进行比较。因此,我们使用一个额外的列表,其中包含我们已经删除的条目的索引(并将它们留在两个 for 循环中)。
可能有更好的方法来执行此操作,但这绝对适用于您的示例。
我正在做一个 NLP 项目,我有一个列表,其中包含一些文本中的字符跨度。 此列表可能如下所示:
[(1,4),(1,7),(4,9),(8,15)]
所以我的任务是 return 所有非重叠对。
如果两个或多个数字对重叠,则跨度最长的对应该 returned。在我的示例中,我想要 return [(1,7),(8,15)]
。我该怎么做?
编辑
我不想像
还没想太多,但下面的方法应该可以解决问题:
spans = [(1,4),(1,7),(4,9),(8,15)]
del_in = []
for x in spans:
if spans.index(x) in del_in: continue
for y in spans:
if spans.index(y) in del_in: continue
if x == y: continue
if len(set(list(range(x[0],x[1]+1))) & set(list(range(y[0],y[1]+1)))) > 0:
if len(list(range(x[0],x[1]+1))) > len(list(range(y[0],y[1]+1))):
del_in.append(spans.index(y))
spans.pop(spans.index(y))
elif len(list(range(y[0],y[1]+1))) > len(list(range(x[0],x[1]+1))):
del_in.append(spans.index(x))
spans.pop(spans.index(x))
print(spans)
会输出:
[(1, 7), (8, 15)]
简短说明:
我们开始遍历跨度列表(迭代 x
)。对于每个元组,我们再次遍历列表(迭代 y
),忽略来自 x
(if x == y: continue
) 的元组。然后,我们将每个元组转换为一个列表(例如 (1,4)
到 [1, 2, 3, 4]
)和 list(range())
并比较列表(尽可能与 set()
)以查看它们是否有任何元素常见的。如果返回对象的长度大于 0,我们比较两个列表的长度,看我们保留哪一个(跨度较大的那个)。随后,我们从列表中删除跨度较小的项目(.pop()
)。由于我们的迭代 x
和 y
仍然通过我们的初始列表,我们需要实施一种机制来防止脚本将项目与已删除的条目进行比较。因此,我们使用一个额外的列表,其中包含我们已经删除的条目的索引(并将它们留在两个 for 循环中)。
可能有更好的方法来执行此操作,但这绝对适用于您的示例。