生成器函数在各种迭代上下文中表现不同

时间:2017-12-31 07:50:52

标签: python-3.x

所以我有非递归排列的这个生成器函数,当我在for循环中使用它时,我得到了我期望的结果:

>>> for p in permutate3( "abc" ): print( p )
...
['a', 'b', 'c']
['a', 'c', 'b']
['b', 'a', 'c']
['b', 'c', 'a']
['c', 'a', 'b']
['c', 'b', 'a']

但是一旦我在列表中使用它或使用参数解包打印,我得到了这个奇怪的输出:

>>> list( permutate3( "abc" ) )
[['c', 'b', 'a'], ['c', 'b', 'a'], ['c', 'b', 'a'], ['c', 'b', 'a'], ['c', 'b', 'a'], ['c', 'b', 'a']]
>>> print( *permutate3( "abc" ) )
['c', 'b', 'a'] ['c', 'b', 'a'] ['c', 'b', 'a'] ['c', 'b', 'a'] ['c', 'b', 'a'] ['c', 'b', 'a']

为什么会这样?

该功能本身是:

def permutate3( s ):
    l = len( s )
    taken = [ False ] * l
    permutation = [ None ] * l
    current = 0
    stack = [ 0 ]

    while True:
        while stack[-1] < l:
            if not taken[ stack[-1] ]:
                permutation[current] = s[ stack[-1] ]
                if current == l-1:
                    yield permutation
                else:
                    taken[ stack[-1] ] = True
                    stack.append( 0 )
                    current+=1
                    break
            stack[-1]+=1
        else:
            stack.pop()
            if len( stack ) == 0:
                break
            else:
                current-=1
                taken[ stack[-1] ] = False
                stack[-1]+=1
                continue

2 个答案:

答案 0 :(得分:1)

假的我。我的函数每次都会产生对同一个对象的引用,该函数由后续排列的函数改变。显然它应该是产量列表(置换)。

答案 1 :(得分:0)

我没有完全看到这种行为的原因,但请尝试更改

permutation = [ None ] * l

permutation = [None for _ in range(l)]

在第一个示例中,列表的所有元素都是相同的对象,而在第二个示例中,将有不同的对象。