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'])]