繁体   English   中英

使用生成器生成排列

[英]Generating permutations using generators

我正在编写一个程序来生成字符串的所有排列:

def print_permutations_wrapper(str):
    strList = str.split()
    print_permutations(strList, 0, len(strList))


def print_permutations(strList: list, start: int, end: int):
    if start >= end - 1:
        print(strList)
        return

    print_permutations(strList, start+1, end)
    for i in range(start+1, end):
        strList[start], strList[i] = strList[i], strList[start]
        print_permutations(strList, start+1, end)
        strList[i], strList[start] = strList[start], strList[i]


def main():
    str = 'a b c'
    print_permutations_wrapper(str)


if __name__ == "__main__":
    main()

它可以正常工作,但我不想使用yield来将其延迟返回,而不是打印它:

def print_permutations_wrapper(str):
    strList = str.split()
    yield from print_permutations(strList, 0, len(strList))


def print_permutations(strList: list, start: int, end: int):
    if start >= end - 1:
        yield strList
        return

    yield from print_permutations(strList, start+1, end)
    for i in range(start+1, end):
        strList[start], strList[i] = strList[i], strList[start]
        yield from print_permutations(strList, start+1, end)
        strList[i], strList[start] = strList[start], strList[i]


def main():
    str = 'a b c'
    x = print_permutations_wrapper(str)
    print(list(x))

if __name__ == "__main__":
    main()

我得到的输出是:

[['a', 'b', 'c'], ['a', 'b', 'c'], ['a', 'b', 'c'], ['a', 'b', 'c'], ['a', 'b', 'c'], ['a', 'b', 'c']]

而不是所有排列。
如何纠正呢?

我正在使用Python 3.7。

使用第二个程序,但是添加一个print(strList)将显示generator函数产生了您期望的结果,但是最终输出显然不是您期望的结果。 这是由于这样的事实:结构化的程序带有一个列表,但是对同一副本执行所有操作(假定限制了内存的使用)。 您也可以通过以下方式进行验证

>>> strList = ['a', 'b', 'c'] 
>>> items = list(print_permutations(strList, 0, 3))
>>> items[0] is items[1]
True
>>> items[0] is strList
True

显然, items中的每个items都与传入的原始strList相同。鉴于问题的简单性,可以通过产生列表的浅表副本来避免此问题。 因此,函数的相关yield部分将变为

def print_permutations(strList: list, start: int, end: int):
    if start >= end - 1:
        yield list(strList)
        return

现在运行它应该产生:

>>> strList = ['a', 'b', 'c'] 
>>> items = list(print_permutations(strList, 0, 3))
>>> items[0] is items[1]
False

另外,排列实际上是标准库的一部分,可通过itertools.permutation

相关: “最小惊讶”和可变的默认参数

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM