首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >除了python对生成器输入的排列之外,还有其他选择吗?

除了python对生成器输入的排列之外,还有其他选择吗?
EN

Stack Overflow用户
提问于 2017-09-27 17:43:19
回答 2查看 1.4K关注 0票数 6

我试图在itertools.permutations中使用一个无界生成器,但它似乎不起作用。返回生成器永远不会被创建,因为函数只会永远运行。要理解我的意思,请考虑:

代码语言:javascript
运行
复制
from itertools import count, permutations
all_permutations = permutations(count(1), 4)

我是如何想象这个工作的,因为它产生了所有可能的前4个自然数的4长排列。然后,它应该产生所有可能的4长排列前5个自然数,没有重复,所以5必须包括在所有这些。然而,所发生的事情是,python挂在创建all_permutations上。

在我从零开始创建我自己的函数之前,我想知道是否还有其他库可以完成我正在寻找的功能呢?另外,这里内置的函数不应该能够处理这个问题吗?这也许是一个应该解决的错误吗?

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

代码语言:javascript
运行
复制
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
...
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-09-27 18:53:59

问得好!下面是一种高效的方法,可以系统地生成它们,不需要重复(也不需要检查):

  1. 首先,第一n元素的排列;
  2. 然后给出了涉及到前几个元素的n+1**st元素**和n-1的置换
  3. 然后是涉及到前几个元素的n+2n-1等的元素。

换句话说,所绘制的最后一个元素总是包含在当前批处理中。这只会使消耗的源元素保持一个元组(不可避免,因为我们将继续在排列中使用它们)。

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

代码语言:javascript
运行
复制
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,)

示范:

代码语言:javascript
运行
复制
>>> 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)
...
票数 4
EN

Stack Overflow用户

发布于 2017-09-27 18:19:27

就像这样:

代码语言:javascript
运行
复制
from itertools import count, permutations

def my_permutations(gen, n=4):
    i = iter(gen)
    population = []
    seen = set()
    while True:
        for p in permutations(population, n):
            if p not in seen:
                yield p
                seen.add(p)
        population.append(next(i))

请注意,内存的使用正在不断增长,但据我所知,这是无法避免的。

更有效的版本:

代码语言:javascript
运行
复制
def my_permutations(gen, n=4):
    i = iter(gen)
    population = []
    while True:
        population.append(next(i))
        *first, last = population
        perms = permutations(first, n-1)
        yield from (p[:i] + (last,) + p[i:] for p in perms for i in range(n))
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46454108

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档