有人能解释一下这个 python 排列代码吗?

发布于 2024-10-26 13:22:37 字数 508 浏览 4 评论 0原文

我在这里看到了一些排列代码的帖子,但我还没有真正找到一个很好的逐步说明实际发生情况的方法。如果有人能够解释这段代码的每个步骤中实际发生的情况,我将非常感激。我似乎无法完全理解它。我正在查看的代码是 Python 代码,来自 http://snippets.dzone.com/帖子/show/753

def all_perms(str):
    if len(str) <=1:
        yield str
    else:
        for perm in all_perms(str[1:]):
            for i in range(len(perm)+1):
                yield perm[:i] + str[0:1] + perm[i:]


for p in all_perms(['a','b','c']):
    print p

I've seen some postings of code for permutations on here but I haven't really been able to find a good step-by-step walk through of what is actually going on. If someone could just explain what is actually happening in each step of this code I would really appreciate it. I can't quite seem to wrap my head around it. The code I'm looking at is in Python and is from http://snippets.dzone.com/posts/show/753.

def all_perms(str):
    if len(str) <=1:
        yield str
    else:
        for perm in all_perms(str[1:]):
            for i in range(len(perm)+1):
                yield perm[:i] + str[0:1] + perm[i:]


for p in all_perms(['a','b','c']):
    print p

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

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

发布评论

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

评论(3

零度° 2024-11-02 13:22:37
def all_perms(str):
    # If there is only one item, there can be only one permutation
    # yield the single item
    if len(str) <=1:
        yield str
    else:
        # loop over the permutations returned by a recursive call to all_perms
        # note it is passing a subset of the list passed in.
        for perm in all_perms(str[1:]):
            # for each returned sub-permutation insert the item that
            # wasn't passed into each possible position.
            for i in range(len(perm)+1):
                yield perm[:i] + str[0:1] + perm[i:]


for p in all_perms(['a','b','c']):
    print p

所以你传入['a','b','c']

它调用 all_perms(['b', 'c']) 并调用 all_perms(['c']) 生成“c”。

yield 语句意味着 all_perms() 是一个 生成器它调用自身的事实意味着它正在使用递归。

我建议使用 itertools.permutations 而不是该片段。

def all_perms(str):
    # If there is only one item, there can be only one permutation
    # yield the single item
    if len(str) <=1:
        yield str
    else:
        # loop over the permutations returned by a recursive call to all_perms
        # note it is passing a subset of the list passed in.
        for perm in all_perms(str[1:]):
            # for each returned sub-permutation insert the item that
            # wasn't passed into each possible position.
            for i in range(len(perm)+1):
                yield perm[:i] + str[0:1] + perm[i:]


for p in all_perms(['a','b','c']):
    print p

So you pass in ['a','b','c'].

It calls all_perms(['b', 'c']) and that calls all_perms(['c']) which yields 'c'.

the yield statement means that all_perms() is a generator the fact that it calls itself means it is using recursion.

I'd recommend using itertools.permutations rather than that snippet.

只为一人 2024-11-02 13:22:37

首先,参数str的名称是一个糟糕的选择。这可能是因为它适用于 Phyton 中的所有序列类型,但它应该是 seq 或其他使意图清晰的东西。

  1. 如果列表的长度 <= 1(空或一个元素),则返回列表(这种情况只有一种解决方案)。

  2. 对于所有其他情况:

    a) 创建 str[1:] 的所有排列(即没有头元素的列表)。

    b) 在 a) 中创建的每个排列中的每个位置插入头元素并返回结果

yield 的工作方式有点像 return;主要区别在于,返回当前值,并且当再次调用该函数时,它会继续执行yield之后的指令。

这样,就可以轻松组装结果。

示例:

'a' 给出 'a' (简单)。
'ab' 首先砍掉头部 ('a'),然后创建 b 的所有排列(只有一个:'b' 本身)。现在,头部已插入到每个位置,因此我们最终得到 'ab' (head+list) 和 'ba' (list+head)。

ETC。

First of all, the name of the parameter str is a bad choice. It's probably due to the fact that it works for all kinds of sequence types in Phyton but it should be seq or something to make the intention clear.

  1. If the length of the list is <= 1 (empty or one element) return the list (there is just one solution for this case).

  2. For all other cases:

    a) Create all permutations of str[1:] (i.e. the list just without the head element).

    b) Insert the head element at each position in each permutation created in a) and return the result

yield works a bit like return; the main difference is that the current value is returned and, when the function is called again, it continues with the instruction after the yield.

This way, it's easy to assemble the result.

Example:

'a' gives 'a' (trivial).
'ab' first chops of the head ('a'), then creates all permutations of b (there is just one: 'b' itself). Now the head is inserted at every position, so we end up with 'ab' (head+list) and 'ba' (list+head).

etc.

最近可好 2024-11-02 13:22:37

您看到的是一个迭代器生成器。它是一个返回一个可以循环的对象的函数。

在执行 for 循环期间,all_perms 会执行到达到 yield 为止。 yielded 值作为 p 变量传递到循环。然后在上次方法退出的yield语句之后的位置继续执行all_perms

What you see is a iterator generator. It's a function that returns an object which can be looped over.

during the execution of the for loop, all_perms is executed up to the point where it hits a yield. The value yielded is passed to the loop as p variable. Then the execution of all_perms is continued at the position after the yield statement where the method exited last time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文