对于生成器输入,是否有替代python的排列?

Cra*_*239 5 python generator permutation infinite python-itertools

我试图使用无界的发电机,itertools.permutations但它似乎没有工作.永远不会创建返回生成器,因为该函数只是永远运行.要了解我的意思,请考虑:

from itertools import count, permutations
all_permutations = permutations(count(1), 4)
Run Code Online (Sandbox Code Playgroud)

我怎么想象这个工作是它产生前4个自然数的所有可能的4长度排列.然后它应该生成前5个自然数的所有可能的4长度排列,没有重复,因此所有这些都必须包含5个.但是,在创建时会挂起python all_permutations.

在我从头开始创建自己的函数之前,我想知道是否有另一个库可以做我正在寻找的东西?此外,这里的内置功能不应该能够处理吗?这可能是一个应该解决的错误吗?

编辑:对于一些迭代......

1 2 3 4
1 2 4 3
...
4 3 2 1
1 2 3 5
1 2 5 3
...
5 3 2 1
1 2 4 5
1 2 5 4
...
Run Code Online (Sandbox Code Playgroud)

ale*_*xis 4

好问题!这是一种有效的方法,可以系统地生成它们,无需重复(并且无需检查):

  1. 首先是第一个元素的排列n
  2. 然后是涉及n+1st 元素n-1前面元素的排列;
  3. 然后涉及第n+2nd 元素和n-1前面的元素,等等。

换句话说,最后绘制的元素始终包含在当前批次中。这只保留了所消耗的源元素的元组(这是不可避免的,因为我们将继续以排列方式使用它们)。

正如您所看到的,我稍微简化了实现:我初始化了 withbase元素n-1并直接进入主循环,而不是步骤 1。

from itertools import islice, permutations, combinations

def step_permutations(source, n):
    """Return a potentially infinite number of permutations, in forward order"""

    isource = iter(source)
    # Advance to where we have enough to get started
    base = tuple(islice(isource, n-1))

    # permutations involving additional elements:
    # the last-selected one, plus <n-1> of the earlier ones
    for x in isource:
        # Choose n-1 elements plus x, form all permutations
        for subset in combinations(base, n-1):
            for perm in permutations(subset + (x,), n):
                yield perm

        # Now add it to the base of elements that can be omitted 
        base += (x,)
Run Code Online (Sandbox Code Playgroud)

示范:

>>> for p in step_permutations(itertools.count(1), 3):
    print(p)

(1, 2, 3)
(1, 3, 2)
(2, 1, 3)
(2, 3, 1)
(3, 1, 2)
(3, 2, 1)
(1, 2, 4)
(1, 4, 2)
(2, 1, 4)
(2, 4, 1)
(4, 1, 2)
(4, 2, 1)
(1, 3, 4)
(1, 4, 3)
(3, 1, 4)
(3, 4, 1)
(4, 1, 3)
(4, 3, 1)
(2, 3, 4)
(2, 4, 3)
(3, 2, 4)
...
Run Code Online (Sandbox Code Playgroud)