任何人都可以帮我检查这个python代码?

时间:2011-06-08 07:02:51

标签: python algorithm

当我想写一个简单的排列代码时,我遇到了一个问题,

def permutation(Ori, Curr, used):
  if len(Ori) == len(Curr):
      #print Curr
      return

  for i in xrange(len(Ori)):
      if used[i]:
          continue
      used[i] = True
      Curr.append(Ori[i])
      print Curr,i," after append"
      permutation(Ori, Curr, used)    # further level
      used[i] = False
      print Curr,i," before delete"
      Curr = Curr[0:-1]               # Curr.pop() works
      print Curr,i," after delete"
  return

if __name__ == "__main__":
  used = [False]*3
  Curr = []
  permutation([1,2,3], Curr, used)

虽然结果不正确:

[1] 0  after append
[1, 2] 1  after append
[1, 2, 3] 2  after append
[1, 2, 3] 2  before delete
[1, 2] 2  after delete     <------
[1, 2, 3] 1  before delete <------
[1, 2] 1  after delete
[1, 2, 3] 2  after append
[1, 2, 3] 2  before delete
[1, 2] 2  after delete
[1, 2, 3] 0  before delete
[1, 2] 0  after delete
[1, 2, 2] 1  after append
[1, 2, 2] 1  before delete
[1, 2] 1  after delete
[1, 2, 3] 2  after append
[1, 2, 3] 2  before delete
[1, 2] 2  after delete

我不知道为什么数组在我指出的步骤中有额外的数字。


对不起,也许我还没有明白我的问题,我只是想知道递归返回列表的原因,我认为它已被缩小。 我写了另一段代码,谁能告诉我两个注释句子之间的区别?(A = A [0:-1]和A.pop())

def f(A):
     if(len(A) == 10):
         return
     A.append('a')
     f(A)
     print A
 #   A = A[0:-1]                             
 #   A.pop()
     return

 if __name__ == "__main__":
    f([])

2 个答案:

答案 0 :(得分:4)

permutation(Ori, Curr, used)    # further level

您正在传递指向列表的指针,而不是列表的副本。执行此操作时,permutation修改Curr时,您会在调用上下文中看到修改。一种可能的解决方案是致电

permutation(Ori, Curr[:], used)    # further level

传递了Curr的副本。

为什么Curr.pop()有效?

因为它会修改Curr。它确实在函数返回之前从Curr中删除了元素。

使用Curr = Curr[0:-1]创建一个Curr的副本,但没有一个元素。该元素不会从原始列表中删除(调用上下文仍然可以访问该列表)。所以它几乎没有做任何事情,因为一旦函数返回,就会忘记没有最后一个元素的新列表。

另一种可能的解决方案是不要更改收到的Curr - 替换

Curr.append(Ori[i])

Curr = Curr + [Ori[i]]

答案 1 :(得分:1)

已经有一个生成排列的功能:

http://docs.python.org/library/itertools.html#itertools.permutations

根据我的拙见,示例代码(根据product定义)是“通常的”基于生成器的实现。

如果考虑有用,这里是生成迭代的所有排列的代码:

def permutations(iter):
    """
        >>> print(list( permutations(range(3)) ))
        [[0, 1, 2], [0, 2, 1], [1, 0, 2], [1, 2, 0], [2, 0, 1], [2, 1, 0]]
    """
    elements = list(iter)

    # base case
    if len(elements)==0:
        yield []

    for i,elem in enumerate(elements):
        withoutElem = elements[:i]+elements[i+1:]
        for perm in permutations(withoutElem):
            yield [elem]+perm