4

情况是这样的: mylist = range(100)我有一个从src=1到的不连续路径,dest=99其中的每个pre[100]值都代表elem. path问题是:我怎样才能得到from toelems中的所有内容。可以这样做:pathdestsrc

    path = []
    i = dst
    while i != src:
      path.append(i)
      i = pre[i]
    path.append(src)

但是,有没有更简单的方法可能只使用一个语句?

样本输入

dst, src = 3, 2
pre = [2, 0, 3, 1]

输出

[3, 1, 0, 2]   #It just have to follow the path with the indices from 3 to 2.

解释:

              src dst
                vv
指数:0 1 2 3
上一页 : 2 0 3 1

从dest 3开始,前身是1,所以我们去1。
从节点 1 开始,前任是 0,所以我们去 0。
从节点 0 开始,前任是 2,所以我们去 2。
2 是 src,所以我们完成了。
4

3 回答 3

4

Pythonic 方法是使用现有循环,或使用等效的生成器函数:

def gen_path(src, dst, pre):
    while dst != src:
        yield dst
        dst = pre[dst]
    yield src

然后要获得一个列表,你可以用list(gen_path(src, dst, pre)).

没有办法在单个基本表达式中执行此操作,因为涉及到状态(您所在路径中的哪个节点)。可能可以使用复杂的、hackish 的东西,比如 2-argumentnextlambdas 和默认参数,但你不想去那里。

于 2013-11-15T04:39:33.117 回答
4

注意:我推荐这个。在实际代码中,我会编写循环。循环简单明了。循环已经是pythonic了。也许使用yield而不是具体化列表,但这很容易。

正如我曾经说过的那样:“对我来说,似乎不符合 Python 的事情是花时间担心让完全清晰的代码更符合 Python 风格。需要数小时思考的 Python 风格并不是真正的 Python 风格。”


但出于娱乐目的,并且因为小马队刚刚赢了,单线:

>>> from itertools import takewhile, accumulate, repeat
>>> dst, src = 3, 2
>>> pre = [2, 0, 3, 1]
>>> list(takewhile(lambda x: x != src, 
                   accumulate(repeat(dst), lambda x,y: pre[x]))) + [src]
[3, 1, 0, 2]

这仅适用于 Python >= 3.3,其中accumulate接受二进制参数函数作为其第二个参数。这在您想要一个给出部分结果的情况下很有用reduce,并且提醒大家这个新功能是我对这个答案的唯一借口。

于 2013-11-15T04:41:17.647 回答
2

不被@DSM 忽略

z = lambda i=dst, p=[]: p if p.append(i) or i==src else z(pre[i]); z()

不用说 - 没有人应该使用这样的代码

于 2013-11-15T04:46:37.127 回答