在元组列表中查找重叠元素?
Find overlapping elements in a list of tuples?
根据我对交集函数的理解,它发现列表中元素之间的完全重叠。例如:
tup_1 = [(1,2,3),(4,5,6)]
tup_2 = [(4,5,6)]
ol_tup = set(tup_1).intersection(tup_2)
print ol_tup
会产生:
set([(4, 5, 6)])
但是,假设我的元组列表是这样设置的:
tup_1 = [(1,2,3),(4,5,5)]
tup_2 = [(4,5,6)]
tup_1 中的第二个元组和 tup_2 中的第一个元组的两个元素有重叠。如果我想 python 到 return 这两个元组:(4,5,5) 和 (4,5,6),有没有比这个嵌套 for 循环(下面)更简单的方法?
for single_tuple_1 in tup_1:
for single_tuple_2 in tup_2:
if single_tuple_1[0] == single_tuple_2[0] and single_tuple_1[1] == single_tuple_2[1]:
print single_tuple_1,single_tuple_2
编辑:
对于这种情况,假设顺序很重要并假设元组包含 5 个元素:
tup_1 = [(1,2,3,4,5),(4,5,6,7,8),(11,12,13,14,15)]
tup_2 = [(1,2,3,4,8),(4,5,1,7,8),(11,12,13,14,-5)]
我想找到在各自的前 4 个元素中相互交叉的元组。所以结果应该是:
[(1,2,3,4,5),(1,2,3,4,8),(11,12,13,14,15),(11,12,13,14,-5)]
代码将如何更改以适应这种情况?
这是使用列表理解的一种方式。编写的逻辑检查至少 2 个元素的重叠。
请注意,如果 没有 重叠,您将只剩下 tup_2
的一个元素,但可以轻松识别。
from itertools import chain
tup_1 = [(1,2,3),(4,5,5)]
tup_2 = [(4,5,6)]
y = sorted(tup_2[0])
res = [i for i in chain(tup_1, tup_2) if
sum(i==j for i, j in zip(sorted(i), y)) > 1]
print res
[(4, 5, 5), (4, 5, 6)]
如果您想 return 所有 "overlapping" 元组对,则无法比较所有对,即二次算法。但是您可以使用列表理解使代码更优雅,product
用于组合,zip
和 sum
用于比较:
>>> tup_1 = [(1,2,3),(4,5,5),(7,8,9)]
>>> tup_2 = [(4,5,6),(0,5,5),(9,8,7)]
>>> [(a, b) for (a, b) in itertools.product(tup_1, tup_2)
... if sum(1 for ai, bi in zip(a, b) if ai == bi) >= 2]
[((4, 5, 5), (4, 5, 6)), ((4, 5, 5), (0, 5, 5))]
注意:这会检查两个元组是否在至少两个位置具有相同的元素,即顺序很重要。如果顺序无关紧要,您可以将 a
和 b
转换为 set
并检查它们交集的大小,但是对于重复的数字,即 [=18 的交集,这可能会失败=] 和 (1,1,3)
只是 1
而不是 2
.
如果你只想匹配前两个,或者前两个和最后两个元素,你可以比较一致析取中元组的切片:
>>> [(a, b) for (a, b) in itertools.product(tup_1, tup_2)
... if a[:2] == b[:2]]
[((4, 5, 5), (4, 5, 6))]
>>> [(a, b) for (a, b) in itertools.product(tup_1, tup_2)
... if a[:2] == b[:2] or a[-2:] == b[-2:]]
[((4, 5, 5), (4, 5, 6)), ((4, 5, 5), (0, 5, 5))]
根据我对交集函数的理解,它发现列表中元素之间的完全重叠。例如:
tup_1 = [(1,2,3),(4,5,6)]
tup_2 = [(4,5,6)]
ol_tup = set(tup_1).intersection(tup_2)
print ol_tup
会产生:
set([(4, 5, 6)])
但是,假设我的元组列表是这样设置的:
tup_1 = [(1,2,3),(4,5,5)]
tup_2 = [(4,5,6)]
tup_1 中的第二个元组和 tup_2 中的第一个元组的两个元素有重叠。如果我想 python 到 return 这两个元组:(4,5,5) 和 (4,5,6),有没有比这个嵌套 for 循环(下面)更简单的方法?
for single_tuple_1 in tup_1:
for single_tuple_2 in tup_2:
if single_tuple_1[0] == single_tuple_2[0] and single_tuple_1[1] == single_tuple_2[1]:
print single_tuple_1,single_tuple_2
编辑:
对于这种情况,假设顺序很重要并假设元组包含 5 个元素:
tup_1 = [(1,2,3,4,5),(4,5,6,7,8),(11,12,13,14,15)]
tup_2 = [(1,2,3,4,8),(4,5,1,7,8),(11,12,13,14,-5)]
我想找到在各自的前 4 个元素中相互交叉的元组。所以结果应该是:
[(1,2,3,4,5),(1,2,3,4,8),(11,12,13,14,15),(11,12,13,14,-5)]
代码将如何更改以适应这种情况?
这是使用列表理解的一种方式。编写的逻辑检查至少 2 个元素的重叠。
请注意,如果 没有 重叠,您将只剩下 tup_2
的一个元素,但可以轻松识别。
from itertools import chain
tup_1 = [(1,2,3),(4,5,5)]
tup_2 = [(4,5,6)]
y = sorted(tup_2[0])
res = [i for i in chain(tup_1, tup_2) if
sum(i==j for i, j in zip(sorted(i), y)) > 1]
print res
[(4, 5, 5), (4, 5, 6)]
如果您想 return 所有 "overlapping" 元组对,则无法比较所有对,即二次算法。但是您可以使用列表理解使代码更优雅,product
用于组合,zip
和 sum
用于比较:
>>> tup_1 = [(1,2,3),(4,5,5),(7,8,9)]
>>> tup_2 = [(4,5,6),(0,5,5),(9,8,7)]
>>> [(a, b) for (a, b) in itertools.product(tup_1, tup_2)
... if sum(1 for ai, bi in zip(a, b) if ai == bi) >= 2]
[((4, 5, 5), (4, 5, 6)), ((4, 5, 5), (0, 5, 5))]
注意:这会检查两个元组是否在至少两个位置具有相同的元素,即顺序很重要。如果顺序无关紧要,您可以将 a
和 b
转换为 set
并检查它们交集的大小,但是对于重复的数字,即 [=18 的交集,这可能会失败=] 和 (1,1,3)
只是 1
而不是 2
.
如果你只想匹配前两个,或者前两个和最后两个元素,你可以比较一致析取中元组的切片:
>>> [(a, b) for (a, b) in itertools.product(tup_1, tup_2)
... if a[:2] == b[:2]]
[((4, 5, 5), (4, 5, 6))]
>>> [(a, b) for (a, b) in itertools.product(tup_1, tup_2)
... if a[:2] == b[:2] or a[-2:] == b[-2:]]
[((4, 5, 5), (4, 5, 6)), ((4, 5, 5), (0, 5, 5))]