有没有一种优雅的方法来跟踪Python中连接项的集合?

时间:2011-06-01 17:46:25

标签: python

对于某段代码,我需要找到一种识别某些别名的方法。事实是,事先并不知道这些别名是什么。

这些是我的要求:

  • 如果 A B 是别名, B C 是别名, A < / em>和 C 也应该是别名。
  • 当以任何方式连接时,应合并两组别名。
  • 在每组别名中,一个应该是主别名。

我使用以下解决方案,使用归结为集合词典的内容:

class Alias(object):
    def __init__(self, initial):
        self._set = {initial}
        self.initial = initial
    def add(self, alias):
        self._set.add(alias)
    def merge(self, other):
        self._set.update(other._set)
    def __iter__(self):
        return iter(self._set)

class AliasDict(object):
    def __init__(self):
        self._dict = {}
    def add(self, one, other):
        if one in self._dict:
            if other in self._dict: #merge!
                self._dict[one].merge(self._dict[other])
                for k in self._dict[other]:
                    self._dict[k] = self._dict[one]
            else:
                self._dict[one].add(other)
        elif other in self._dict:
            self._dict[other].add(one)
        else:
            self._dict[one] = self._dict[other] = Alias(one)
            self._dict[one].add(other)
    def get(self, n):
        return self._dict.get(n)
    def __contains__(self, s):
        return s in self._dict

这可以改进吗?例如,通过在标准库中使用一个类(我已经搜索过,但我可能错过了一些有用的东西。)

2 个答案:

答案 0 :(得分:3)

您是否考虑过使用disjoint set?它的速度几乎为O(1) easy to implement,并且似乎完全符合您的要求。

答案 1 :(得分:2)

这是你可以在图表上映射的东西,所以我会这样做:

from networkx import Graph
from networkx.algorithms.components.connected import connected_components

# see aliases as the edges between nodes in a graph
aliases = [('A', 'B'), ('B', 'C'), ('D','E')]

g = Graph( aliases )

# connected components are alias groups
print connected_components(g) # [['A', 'C', 'B'], ['E', 'D']]

您没有指定哪个别名应该是主要别名,所以您也可以从这些列表中选择第一个别名。

networkx module