我试图理解“收益率”。
首先,我无法理解的代码如下。
def permutations(seq):
if len(seq) <= 1: yield seq
else:
for perm in permutations(seq[1:]):
for i in range(len(perm)+1):
yield perm[i:] + seq[0:1] + perm[:i]
print list(permutations(['police', 'buffalo', 'fish']))
结果如下:
[['fish', 'buffalo', 'police'], ['buffalo', 'police', 'fish'], ['police', 'fish', 'buffalo'], ['buffalo', 'fish', 'police'], ['fish', 'police', 'buffalo'], ['police', 'buffalo', 'fish']]
我对“产量”的承诺水平只是用于生成。我可以理解下面的代码。
def reverse(data):
for index in range(len(data) -1, -1, -1):
yield data[index]
for char in reverse('golf'):
print(char)
f
l
o
g
我的水平只是上面的理解..但是随着递归,我无法理解......请解释。谢谢
答案 0 :(得分:3)
是的,产量适用于发电机。这意味着在调用时,它们会返回迭代器。生成器可以是递归的:它们将自己调用,获取迭代器并迭代它,在每次迭代时,它们可以根据自己的喜好产生尽可能多的元素。
在您的示例中,permutations
是一个始终在列表上返回迭代器的生成器。
if len(seq) <= 1: yield seq
很简单:在简单的情况下,只需生成一个列表,seq
本身。
for perm in permutations(seq[1:]):
...
表示“现在迭代不同的列表序列”,在这种情况下,它是第一个之后元素的所有排列的序列。在每次迭代中,我们都有一个嵌套循环,它将第一个元素插入到排列的每个位置并产生结果。
我希望有所帮助。这对我来说有点难,因为我不确切地知道你对此感到困惑。
更新: OP想知道为什么第一个结果的顺序相反。考虑一下:
yield perm[i:] + seq[0:1] + perm[:i]
对于第一个结果(i = 0),这相当于yield perm + seq[0:1]
- 第一个元素被发送到产生列表的 end 。通过归纳,该结果与seq
相反。如果您希望第一个结果为['police', 'buffalo', 'fish']
,那么您可以执行以下操作:
yield perm[:i] + seq[0:1] + perm[i:]
答案 1 :(得分:1)
您提供的代码根据此算法运行:
原始代码在如何实现第3.1.2点方面略显奇怪。通过使用更多变量来更清楚地显示与算法的关系,我们可以更清楚地说明这一点 - 这假设您使用的是Python 3:
def permutations(seq):
if len(seq) <= 1:
yield seq
else:
first, *rest = seq
for perm in permutations(rest):
for i in range(len(perm)+1):
before = perm[:i]
after = perm[i:]
yield after + [first] + before
正如您所看到的,最后一行切换排列的开始和结束是没有实际意义的。它可以很容易地before + [first] + after
,但作者决定不这样做。这并不影响算法的工作方式 - 它会找到 all 的顺序,包括镜像的顺序 - 但这意味着它产生它们的顺序可能有点奇怪。
您也可以使用类似的递归生成器来实现reverse
。在这种情况下,算法是:
在Python中,它看起来像这样:
def reverse(seq): 如果len(seq)&lt; = 1: 返回seq
first, *rest = seq
for item in reverse(rest):
yield item
# Or you could use:
# yield from reverse(rest)
# Instead of the above loop
yield first