有没有一种方法可以“暂停"或部分使用Python中的生成器,然后在中断的地方恢复使用? [英] Is there a way to 'pause' or partially consume a generator in Python, then resume consumption later where left off?

查看:77
本文介绍了有没有一种方法可以“暂停"或部分使用Python中的生成器,然后在中断的地方恢复使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此处有一个相关问题.我正在尝试对项目进行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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆