我在python中有一个函数,它在列表推导中以递归方式编程。但我不清楚它究竟发生了什么!
def permut(s,l):
if l == []: return [[s]]
return [ e + [l[0]] for e in permut(s, l[1:])] + [l+[s]]
该函数获取两个参数,首先是一个String,第二个是一个列表,它返回列表中String的排列。
permut('a', [1,2,3])
[['a', 3, 2, 1], [3, 'a', 2, 1], [2, 3, 'a', 1], [1, 2, 3, 'a']]
有人可以解释一下,列表理解会发生什么?
答案 0 :(得分:3)
如果列表推导语法让你失望,你可以按如下方式重写这个函数,并在此过程中添加一些调试print()
:
def permut(s,l):
print("Entering function permut()")
print("Parameters:\ns: {}\nl: {}".format(s,l))
if l == []:
print("End of recursion reached, returning {}".format([[s]]))
return [[s]]
result = []
for e in permut(s, l[1:]):
result.append(e + [l[0]])
result += [l + [s]]
print("Returning {}".format(result))
return result
这是你得到的输出:
>>> permut('a', [1,2,3])
Entering function permut()
Parameters:
s: a
l: [1, 2, 3]
Entering function permut()
Parameters:
s: a
l: [2, 3]
Entering function permut()
Parameters:
s: a
l: [3]
Entering function permut()
Parameters:
s: a
l: []
End of recursion reached, returning [['a']]
Returning [['a', 3], [3, 'a']]
Returning [['a', 3, 2], [3, 'a', 2], [2, 3, 'a']]
Returning [['a', 3, 2, 1], [3, 'a', 2, 1], [2, 3, 'a', 1], [1, 2, 3, 'a']]
[['a', 3, 2, 1], [3, 'a', 2, 1], [2, 3, 'a', 1], [1, 2, 3, 'a']]
答案 1 :(得分:2)
首先,您在递归a
电话中有s
而不是permut
。
return [ e + [l[0]] for e in permut(a, l[1:])] + [l+[s]]
首先,它计算permut(s, l[1:])
,即:尝试置换s
和列表中没有第一个元素的部分。它抛出第一个元素,只要有任何东西,然后递归调用返回[[s]]。
现在,在调用中向后移动,s
被“添加”到递归创建列表的每个元素,然后附加l
,结果为:
# l == []
return [['a']]
# e == ['a']
# l == [3], l[0] == 3
return [['a'] + [3]] + [[3] + [a]]
# equals [['a', 3], [3, 'a']]
# e == ['a', 3] then [3, 'a']
# l == [2, 3], l[0] == 2
return [['a', 3] + [2], [3, 'a'] + [2]] + \
[[2, 3] + [a]]
# equals [['a', 3, 2], [3, 'a', 2], [2, 3, 'a']]
# e == ['a', 3, 2] then [3, 'a', 2] then [2, 3, 'a']
# l == [1, 2, 3], l[0] == 1
return [['a', 3, 2] + [1], [3, 'a', 2] + [1], [2, 3, 'a'] + [1]] + \
[[1, 2, 3] + ['a']]
# equals [['a', 3, 2, 1], [3, 'a', 2, 1], [2, 3, 'a', 1], [1, 2, 3, 'a']]
阅读可能并不美观,但它有点有效。您可以看到e
被提取为上一级返回的列表的单个元素。
您也可以尝试:
def tee(parm):
print parm
return parm
并将permut
重新定义为:
def permut(s,l):
if l == []: return [[s]]
return [ e + [l[0]] for e in tee(permut(s, l[1:]))] + [l+[s]]
我的输出:
[['a']]
[['a', 3], [3, 'a']]
[['a', 3, 2], [3, 'a', 2], [2, 3, 'a']]
[['a', 3, 2, 1], [3, 'a', 2, 1], [2, 3, 'a', 1], [1, 2, 3, 'a']]
其中包含递归调用。