如何为一个案例迭代更多pythonic?

时间:2013-11-15 03:54:44

标签: python

以下是这种情况: mylist = range(100)我有一条从src=1dest=99的不连续路径,其数组为pre[100],其中每个值代表elem中的最后一个path }。 问题是:如何从elemspath获取dest中的所有src。可以这样做:

    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
                v  v
Indices:  0  1  2  3
Pre    :  2  0  3  1

From dest 3, the predecessor is 1, so we go to 1.
From node 1, the predecessor is 0, so we go to 0.
From node 0, the predecessor is 2, so we go to 2.
2 is src, so we're done.

3 个答案:

答案 0 :(得分: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参数nextlambda s和默认参数,但你不想去那里。

答案 1 :(得分:4)

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

正如我曾经说过的那样:“对我来说似乎是单声道的是花时间担心将完全清晰的代码变得更加诡异。需要数小时思考的Pythonicness并不是真正的Pythonicness。”


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

>>> 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给出部分结果的情况非常有用,并且提醒每个人这个新功能是关于这个答案唯一的借口..

答案 2 :(得分:2)

不要被@DSM取消

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

毋庸置疑 - 没有人应该使用这样的代码