有没有一种方法可以“暂停"或部分使用Python中的生成器,然后在中断的地方恢复使用? [英] Is there a way to 'pause' or partially consume a generator in Python, then resume consumption later where left off?
问题描述
此处有一个相关问题.我正在尝试对此项目进行Euler挑战HackerRank.它要求您能够导出字符串"abcdefghijklm"的第 n 个排列.有13个!排列.
There is a related question here. I am attempting to do this project Euler challenge on HackerRank. What it requires is that you are able to derive the nth permutation of a string "abcdefghijklm". There are 13! permutations.
我尝试了一个使用for num, stry in zip(range(1, math.factorial(13)), itertools.permutations("abcdefghijklm"):
的简单解决方案.可以,但是超时.
I tried a simple solution where I used for num, stry in zip(range(1, math.factorial(13)), itertools.permutations("abcdefghijklm"):
. That works, but it times out.
最好的做法是将每个值存储在dict
中,然后执行以下操作:
What would be really nice is to store each value in a dict
as I go along, and do something like this:
import itertools
import math
strt = "abcdefghijklm"
dic = {}
perms_gen = itertools.permutations(strt)
idxs_gen = range(1, math.factorial(13))
curr_idx = 0
test_list = [1, 2, 5, 10]
def get_elems(n):
for num, stry in zip(idxs_gen, perms_gen):
print(num) # debug
str_stry = "".join(stry)
dic[num] = str_stry
if num == n:
return str_stry
for x in test_list:
if curr_idx < x:
print(get_elems(x))
else:
print(dic[x])
这不起作用.我得到以下输出:
This doesn't work. I get this output instead:
1
abcdefghijklm
1
2
abcdefghijlkm
1
2
3
4
5
abcdefghikjml
1
2
3
4
5
6
7
8
9
10
abcdefghilmkj
在我写这个问题时,我显然找到了答案……继续.
As I was writing this question, I apparently found the answer... to be continued.
推荐答案
标题中问题的答案为是",您可以暂停并重新启动.怎么样?
The answer to the question in the title is "yes", you can pause and restart. How?
(对我而言)意外地zip()
显然重新启动了压缩生成器,尽管先前已对其进行了定义(也许有人可以告诉我为什么会这样?).因此,我添加了main_gen = zip(idxs_gen, perms_gen)
并从for num, stry in zip(idxs_gen, perms_gen):
更改为for num, stry in main_gen:
.然后,我得到以下输出,假设字符串正确,则正是我想要的:
Unexpectedly (to me), apparently zip()
restarts the zipped generators despite them being previously defined (maybe someone can tell me why that happens?). So, I added main_gen = zip(idxs_gen, perms_gen)
and changed to for num, stry in zip(idxs_gen, perms_gen):
to for num, stry in main_gen:
. I then get this output, which, assuming the strings are correct, is exactly what I wanted:
1
abcdefghijklm
2
abcdefghijkml
3
4
5
abcdefghijmkl
6
7
8
9
10
abcdefghiklmj
更改后,代码如下:
import itertools
import math
strt = "abcdefghijklm"
dic = {}
perms_gen = itertools.permutations(strt)
idxs_gen = range(1, math.factorial(13))
main_gen = zip(idxs_gen, perms_gen)
curr_idx = 0
test_list = [1, 2, 5, 10]
def get_elems(n):
for num, stry in main_gen:
print(num)
str_stry = "".join(stry)
dic[num] = str_stry
if num == n:
return str_stry
for x in test_list:
if curr_idx < x:
print(get_elems(x))
else:
print(dic[x])
这篇关于有没有一种方法可以“暂停"或部分使用Python中的生成器,然后在中断的地方恢复使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!