chr*_*yss 3 python recursion exception generator permutation
作为练习,我一直在尝试各种方法来生成Python中列表的所有排列 - 递归,非递归...... - 并将性能与之比较itertools.permutations().但是我遇到了递归方法的生成器版本的问题,它没有完全干净地完成StopIteration异常,而是抛出一个IndexError:
def spawnperms(alist):
"""same algorithm as recursive option, but a generator"""
if (alist == []):
yield []
for perm in spawnperms(alist[:-1]):
for i in range(len(perm)+1):
yield perm[:i] + [alist[-1]] + perm[i:]
Run Code Online (Sandbox Code Playgroud)
从Python解释器调用它:
>>> for i in spawnperms(range(3)):
... print i
...
[2, 1, 0]
[1, 2, 0]
[1, 0, 2]
[2, 0, 1]
[0, 2, 1]
[0, 1, 2]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in spawnperms
File "<stdin>", line 5, in spawnperms
File "<stdin>", line 5, in spawnperms
File "<stdin>", line 7, in spawnperms
IndexError: list index out of range
Run Code Online (Sandbox Code Playgroud)
哎哟.我尝试单步执行它pdb,这几乎在我的大脑中创建了一个堆栈溢出,但我所理解的是递归"向下"到空列表,然后外部(我认为)for循环用完了索引.
我该如何更正我的代码?
编辑:从Mark Byers的一个看似简单的正确答案中学到的一点是,清晰的编码实践可以防止错误.如果我曾经else系统地使用过if,不管我是否认为这种情况可以重新审视,这都不会发生.它仍然感觉非常愚蠢!
你错过了一个else:
if (alist == []):
yield []
else:
for ...
Run Code Online (Sandbox Code Playgroud)
这是因为yield不像以下那样表现return.yield 请求下一个值后,在语句后继续执行.
| 归档时间: |
|
| 查看次数: |
229 次 |
| 最近记录: |