拓扑排序、递归、使用生成器

发布于 2024-07-04 21:13:41 字数 513 浏览 12 评论 0原文

数据:依赖列表,已验证为非循环。 所以在这里,“a”取决于“b”、“c”(c 取决于 d)等...

A = { 'a' :  dict(b=1, c=1),
    'c' : dict(d=1),
    'd' : dict(e=1,f=1,g=1),
    'h' : dict(j=1)
    }

我想要一个自上而下的递归解决方案,比方说,找到从 'a': a, c, d, e, g, f, b

所以,现在(非生成器解决方案):

def get_all(D,k):
    L = []
    def get2(D,k):
        L.append(k)
        for ii in D.get(k,[]):
            get2(D, ii)
    get2(D,k)
    return L

显然,这非常弱:)我一直在绞尽脑汁思考如何如何获得里面有收益,我很感激你们能带来的任何 py-foo 。

Data: a dependency list, already verified to be acyclic. So here, 'a' depends on 'b','c' (c depends on d), etc...

A = { 'a' :  dict(b=1, c=1),
    'c' : dict(d=1),
    'd' : dict(e=1,f=1,g=1),
    'h' : dict(j=1)
    }

I'd like to have a top-down, recursive solution to let's say, find the chain starting at
'a': a, c, d, e, g, f, b

So, right now (a non-generator solution):

def get_all(D,k):
    L = []
    def get2(D,k):
        L.append(k)
        for ii in D.get(k,[]):
            get2(D, ii)
    get2(D,k)
    return L

Obviously, this is pretty weak :) I've been banging my head about how to how to get yields inside there, and I'd appreciate any py-foo y'all can bring to this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧伤还要旧人安 2024-07-11 21:13:41

两个答案都给出相同的结果,但如果我对问题的阅读是正确的,则对给定图形的简单更改给出错误的答案 - 如果您从“b”添加对“c”的依赖(这不会引入循环)如图所示)输出为:
A
C
d
e
G
F

d
e
G
F

这并不完全有帮助。 尝试这个小变化,它会跟踪图表中的哪些节点已经被访问过:

def get_all(D, k, seen=None):
    if not seen:
        seen = set( )
    if k not in seen:
        seen.add(k)
        yield k
        for ii in D.get(k, []):
            for jj in get_all(D, ii, seen):
                yield jj

Both answers give the same result, but if my reading of the question is correct give the wrong answer to a simple alteration to the given graph - if you add a dependency on 'c' from 'b' (which doesn't introduce a cycle as the graph is directed) the output is:
a
c
d
e
g
f
b
d
e
g
f

which isn't totally helpful. Try this small variation, which keeps track of which nodes of the graph have already been visited:

def get_all(D, k, seen=None):
    if not seen:
        seen = set( )
    if k not in seen:
        seen.add(k)
        yield k
        for ii in D.get(k, []):
            for jj in get_all(D, ii, seen):
                yield jj
素罗衫 2024-07-11 21:13:41

试试这个:

#!/usr/bin/env python

def get_all(D, k):
    yield k
    for ii in D.get(k, []):
        for jj in get_all(D, ii):
            yield jj

A = { 'a' : dict(b=1, c=1),
    'c' : dict(d=1),
    'd' : dict(e=1,f=1,g=1),
    'h' : dict(j=1)
    }

for ii in get_all(A,'a'):
    print ii

给我

steve@rei:~/code/tmp
$ python recur.py
a
c
d
e
g
f
b

Try this:

#!/usr/bin/env python

def get_all(D, k):
    yield k
    for ii in D.get(k, []):
        for jj in get_all(D, ii):
            yield jj

A = { 'a' : dict(b=1, c=1),
    'c' : dict(d=1),
    'd' : dict(e=1,f=1,g=1),
    'h' : dict(j=1)
    }

for ii in get_all(A,'a'):
    print ii

Gives me

steve@rei:~/code/tmp
$ python recur.py
a
c
d
e
g
f
b
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文