我才刚刚开始接触python领域,坦白地说,对于以下实现给我带来的结果,我有些困惑。
这只是一个递归函数,应输出给定列表的所有排列。我知道可能有上千种更好的方法可以做到这一点,但这就是我想出的。让我惊讶的是,完全相同的代码在C ++中也可以正常工作;我相信这可能与python *中传递变量的方式有关,但我不确定。
代码:
def permut (s, permut_s):
if not s:
return permut_s
if not permut_s:
last_s = s[-1]
s.pop (-1)
permut_s = [[last_s]]
return permut (s, permut_s)
new_permut_s = []
last_s = s[-1]
for x in range (len (permut_s)):
aux = permut_s[x]
aux = [last_s] + aux
new_permut_s.append (aux)
for y in range (len (aux) - 1):
aux_elem = aux[y]
aux[y] = aux[y + 1]
aux[y + 1] = aux_elem
new_permut_s.append (aux)
s.pop (-1)
return permut (s, new_permut_s)
def main(s, permut_s):
print (permut (s, permut_s))
main ([1,2,3], [])
*之所以这样说,是因为在两行之间进行一些打印显示,在第一个非平凡执行之前,new_permut_s = [[2,3]],之后是[[3,2],[ 3,2]],应为[[2,3],[3,2]]
非常感谢!
答案 0 :(得分:0)
忘记所有可以使用的排列:
import itertools
list(itertools.permutations([1, 2, 3]))
“不要重新发明轮子”是编程中最好的格言之一。
答案 1 :(得分:0)
问题是您多次追加同一列表。因此,您的修改会影响之前的new_permut_s
元素(因为它们可以全部视为与aux
中的元素相同的列表地址)。以下是最简单的解决方案(请参见# THE FIX
):
def permut (s, permut_s):
if not s:
return permut_s
if not permut_s:
last_s = s[-1]
s.pop (-1)
permut_s = [[last_s]]
return permut (s, permut_s)
new_permut_s = []
last_s = s[-1]
for x in range (len (permut_s)):
aux = permut_s[x]
aux = [last_s] + aux
new_permut_s.append (aux)
for y in range (len (aux) - 1):
aux = aux[:] # THE FIX
aux_elem = aux[y]
aux[y] = aux[y + 1]
aux[y + 1] = aux_elem
new_permut_s.append (aux)
s.pop (-1)
return permut (s, new_permut_s)
def main(s, permut_s):
print (permut (s, permut_s))
main ([1,2,3], [])
通过aux = aux[:]
(或aux = aux[0:len(aux)]
),我们获取原始列表,获取其切片(至少在标准库中,它始终是一个新对象),然后分配切片(列表)这里)到相同的变量。
关于是否可以避免这种复制:我不这样认为,因为所有排列的列表应该是独立的。从理论上讲,您可以编写一个类来修补现有列表(例如,每个实例都包含对“全局”列表和某些本地修补程序的引用,然后在访问索引时为索引计算实际值),或者可以合并代码用于复制和交换(以便您通过几个步骤复制原始列表的多个部分)。但是这样的解决方案似乎对您的任务来说是过大的。
PythonTutor.com帮助调试此类问题。特别是,我使用了this "visualization"来调试您的代码。
在REPL中,此类检查非常有用:
>>> out = permut([1,2,3], [])
>>> out[0] is out[1]
True
答案 2 :(得分:0)
您要在输出中附加浅表副本。使用这个:
from copy import deepcopy
def permut (s, permut_s):
print(s)
print(permut_s)
if not s:
return permut_s
if not permut_s:
last_s = s[-1]
s.pop (-1)
permut_s = [[last_s]]
return permut (s, permut_s)
new_permut_s = []
last_s = s[-1]
for x in range (len (permut_s)):
aux = permut_s[x]
aux = [last_s] + aux
new_permut_s.append (deepcopy(aux))
for y in range (len (aux) - 1):
aux_elem = aux[y]
aux[y] = aux[y + 1]
aux[y + 1] = aux_elem
new_permut_s.append (deepcopy(aux))
print("new")
print(new_permut_s)
s.pop (-1)
return permut (s, new_permut_s)
def main(s, permut_s):
print (permut (s, permut_s))
main ([1,2,3], [])