Python中的句柄传递性
我有一套类似这样的两两关系Python中的句柄传递性,python,Python,我有一套类似这样的两两关系 col_combi = [('a','b'), ('b','c'), ('d','e'), ('l','j'), ('c','g'), ('e','m'), ('m','z'), ('z','p'), ('t','k'), ('k', 'n'), ('j','k')] 这种关系的数量足够大,可以单独检查。这些元组表示两个值相同。我想应用及物性并找出常见的组。输出如下所示: [('a','b','c','g'),
col_combi = [('a','b'), ('b','c'), ('d','e'), ('l','j'), ('c','g'),
('e','m'), ('m','z'), ('z','p'), ('t','k'), ('k', 'n'),
('j','k')]
这种关系的数量足够大,可以单独检查。这些元组表示两个值相同。我想应用及物性并找出常见的组。输出如下所示:
[('a','b','c','g'), ('d','e','m','z','p'), ('t','k','n','l','j')]
我尝试了以下代码,但它有错误
common_cols = []
common_group_count = 0
for (c1, c2) in col_combi:
found = False
for i in range(len(common_cols)):
if (c1 in common_cols[i]):
common_cols[i].append(c2)
found = True
break
elif (c2 in common_cols[i]):
common_cols[i].append(c1)
found = True
break
if not found:
common_cols.append([c1,c2])
以上代码的输出如下所示
[['a', 'b', 'c', 'g'], ['d', 'e', 'm', 'z', 'p'], ['l', 'j', 'k'], ['t', 'k', 'n']]
我知道此代码不起作用的原因。因此我想知道如何执行此任务
如果您认为这种关系是自反性的,请提前从elif后的代码中感谢。 如果未按特定顺序提供对,则算法将失败 例如:
(b, c) (a, b) (c, d)
将以两盘结束
b, c, d
及
问题在于使用等价关系对集合进行划分。了解集合论的背景有助于确定一个能够解决问题的库。请参阅。您可以使用和并集/交集操作实现解决方案
col_combi = [('a','b'), ('b','c'), ('d','e'), ('l','j'), ('c','g'),
('e','m'), ('m','z'), ('z','p'), ('t','k'), ('k', 'n'),
('j','k')]
from itertools import combinations
sets = [set(x) for x in col_combi]
stable = False
while not stable: # loop until no further reduction is found
stable = True
# iterate over pairs of distinct sets
for s,t in combinations(sets, 2):
if s & t: # do the sets intersect ?
s |= t # move items from t to s
t ^= t # empty t
stable = False
# remove empty sets
sets = list(filter(None, sets)) # added list() for python 3
print sets
输出:
['m', 'z', 'e', 'd', 'p']
['t', 'k', 'j', 'l', 'n']
['a', 'c', 'b', 'g']
[集合(['a','c','b','g']),集合(['p','e','d','z','m']),集合(['t','k','j','l','n'])]
注意:对于
itertools.compositions
,您可以使用库将其作为图形问题处理:
输出:
['m', 'z', 'e', 'd', 'p']
['t', 'k', 'j', 'l', 'n']
['a', 'c', 'b', 'g']
使用itertools的解决方案,您可以查看
lst =[]
import itertools
for a, b in itertools.combinations(col_combi, 2):
for i in a:
if i in b:
lst.append(set(a+b))
for indi,i in enumerate(lst):
for j in lst:
if i == j:
continue
if i & j:
lst[indi] = i|j
lst.remove(j)
print lst
这项研究的结果是:
[set(['a', 'c', 'b', 'g']), set(['k', 'j', 'l', 'n']), set(['e', 'd', 'm', 'p', 'z'])]
当然,这可以提高效率。我会尽快更新 看起来像是联合查找问题:您可能会这样,您需要指定是否要在输出“链”中保留元组顺序。i、 e.输出是否需要与您呈现的
[('a'、'b'、'c'、'g')、('d'、'e'、'm'、'z'、'p')、('t'、'k'、'n'、'l'、'j')]
(保留元组顺序)或是完全等同于(例如,[('a'、'c'、'g'、'b')、('d'、'e'、'm'、'z'、'p')、('t'、'l'、'j'、'k')对您而言是的)。在将其发布到此处之前,我找到了它不起作用的原因。@vrajs5:您应该在问题中提到这一重要信息。@vrajs5:我确实读过粗体字母,所以我知道您知道您的算法有缺陷的原因。但你没有告诉我们为什么它有缺陷。如果你说了塔里克在回答中提到的话,那会很有帮助。总之,这没什么大不了的。@PM2Ring他知道你知道他知道为什么他的算法有缺陷……哈哈。只是开玩笑而已:-)我就知道你会这么说他真的想要那个么做吗?你们的代码给了我比列表中唯一的值。你确定你理解我的问题吗?@vrajs5我解决了问题solution@wap26-我不知道,但代码在2.7.2中运行良好,但在python中给了我一些帮助3@vrajs5:将set=filter(无,集)
更改为set=list(filter(无,集))
[set(['a', 'c', 'b', 'g']), set(['k', 'j', 'l', 'n']), set(['e', 'd', 'm', 'p', 'z'])]