如何反转集合中的树状链接?

时间:2015-07-29 22:54:47

标签: python algorithm python-3.x

我有一个python脚本,它解析数据块并创建一组对象。这些对象是具有标识符和其他标识符列表的类的实例。标识符是字符串,如果重要的话。数据类似于目录树,但具有许多符号链接。问题是符号链接只沿着树的一个方向。我需要能够查看底部id并说出与之相关的内容。我无法找到一个很好的解释算法,这很容易转换成我的python脚本(主要是因为我不是python程序员,我通常使用C)。

以下是一个示例数据集:

Obj1: id=1, lnk=[3,5,7,9]
Obj2: id=2, lnk=[4,9]
Obj3: id=3, lnk=[4,8,9]
Obj4: id=4, lnk=[6,7]
Obj5: id=5, lnk=[2]
...
my_set = set(Obj1, Obj2, Obj3, Obj4, Obj5, ...)

阅读这些内容为“1使用3,5,7和9”,“2使用4和9”等。

我需要能够输出:

9 is used by [1,2,3]
8 is used by [3]
7 is used by [1,4]
6 is used by [4]
5 is used by [1]
4 is used by [2,3]
3 is used by [1]
2 is used by [5]

或(这些是集合,而不是元组):

9 is used by (1,2,3,5)
8 is used by (1,3)
7 is used by (1,2,3,4,5)
6 is used by (1,2,3,4,5)
5 is used by (1)
4 is used by (1,2,3,5)
3 is used by (1)
2 is used by (1,5)

第一个似乎更容易获得,但第二个是我真正想要的。

2 个答案:

答案 0 :(得分:1)

执行此操作的一种方法是将新的实例变量添加到名为upstream的自定义对象类型中,该变量初始化为None

然后从树的根开始,递归地按照链接向下,在深度优先遍历中,在转到运行列表时附加每个新链接,并将每个链接填充到运行列表的副本。当您点击已将upstream设置为not None的节点时,您可以避免重复。

答案 1 :(得分:1)

如果您对这些对象进行编码:

Obj1 = {1: [3,5,7,9]}
Obj2 = {2: [4,9]}
...

然后你可以将它们全部组合成一个字典:

my_objs = {1: [3,5,7,9], 2: [4,9], ...}

现在您可以像这样创建反向树:

tree = {}
for id, lnks in my_objs.items():
    for lnk in lnks:
        uplnks = tree.get(lnk, [])
        uplnks.append(id)
        tree[lnk] = uplnks

最后,您可以打印树:

def used_by(tree, id, all_lnks=None):
    if all_lnks is None:
        all_lnks = set()
    lnks = tree.get(id)
    if not lnks:
        return all_lnks
    all_lnks.update(lnks)
    for lnk in lnks:
        all_lnks = used_by(tree, lnk, all_lnks)
    return all_lnks

for id in tree.keys():
    print id, 'is used by', list(used_by(tree, id))