如果我们在Python中使用耗尽的发电机进行循环会发生什么?
我正在Python 3中创建一个发电机,该发电机可能会产生一个或更多的值。
我想要的条件是,我想从第二个值开始使用此迭代器循环,依此类推,以该值运行API请求函数。如果发电机仅产生一个值,则不需要执行for循环和相应的代码。如果发电机产生多个值,则从发电机的第二个值等开始执行前循环内部的函数。
我要以第二个值开始的原因是因为已经为API请求访问了第一个值,并且其结果已存储。
我的问题与产生单个值的发电机有关。
我在下面给出代码示例:(我简化了使用print()函数的API请求):
def iterexample(): # creating a simple iterator that return a single value
yield 0
print(0)
iter = iterexample()
next(iter) #generator is consumed once here
for i in iter: #1 generator is exhausted
print(i, ' inside loop') #2 this is skipped because the generator is exhausted
#3 rest of the code outside the loop will be executed
它返回我的期望:只有0是打印的,而不是“ 0 inside loop”
0
我的问题是:
- 它是最安全,最柔软的方法那会吗?它会筹集吗? 有错误吗?
- 它会产生无限循环吗?我很害怕是否会导致 API请求的无限循环。
- 请查看我的#1〜#3评论,在上面的代码中,是我的 正确理解吗?
感谢您的回复和帮助。干杯!
I am creating a generator in python 3 which may yield a single value or more.
The condition that I wanted is, I want to loop with this iterator starting at the second value and so on, running an API request function with that value. If the generator yield only a single value, the for loop and corresponding code is not needed to be executed. If the generator yield more than one value, the function inside the for-loop will be executed starting from the second value of generator and so on.
The reason why I want to start at the second value is because the first value is already accessed for the API request and its result has been stored.
My question is related to a generator that produce a single value.
I give the code example below: (I simplified API Request with print() function):
def iterexample(): # creating a simple iterator that return a single value
yield 0
print(0)
iter = iterexample()
next(iter) #generator is consumed once here
for i in iter: #1 generator is exhausted
print(i, ' inside loop') #2 this is skipped because the generator is exhausted
#3 rest of the code outside the loop will be executed
It returns what I expected: only 0 is printed, not "0 inside loop"
0
My question is:
- Is it the safest and the most pythonic way to do that? will it raise
any error? - Will it produce infinite loop? I am very afraid if it will result as
infinite loop of API request. - Please review my #1 ~ #3 comment in above codes, are my
understanding correct?
Thanks for the response and the help. Cheers!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
一旦发电机耗尽,当询问新值时,它将不断提高
stopiteration
例外。对于循环,可以在升起此例外时终止循环来处理这种情况,这使得将耗尽的发电机传递到用于循环构造器的情况下是安全的。但是,您的代码调用
next
直接,因此仅当它还处理stopiteration
异常时才安全。在这种情况下,您需要记录提供的生成器必须产生1个或更多值或容忍空案例。如果发电机没有返回值,那么您将获得错误。例如,为防止空发电机,您可以将第二个可选默认参数用于
Next
。同样,这取决于发电机。发电机不需要具有最终值。您可以轻松地定义这样的非终止生成器:
如果这是您的关注点,防止永无止境输出的一种方法是使用
islice
,该在消耗了许多值后会切断发电机:Once a generator is exhausted, it will continually raise
StopIteration
exceptions when asked for new values. For loops can handle this case by terminating the loop when this exception is raised, which makes it safe to pass an exhausted generator to a for loop constructor.However, your code calls
next
directly, and is therefore only safe only if it also handleStopIteration
exceptions. In this case you would need to document that the generator provided must produce 1 or more values or be tolerant of the empty case. If the generator returned no values, then you would get an error. e.g.To prevent against empty generators you can use the second optional default argument to
next
.Again this depends on the generator. Generators do not need to have an end value. You can easily define non-ending generators like this:
If this is a concern for you, one way to prevent never ending outputs would be to use an
islice
that cuts off your generator after so many values are consumed:如果我正确理解您的问题:您有一个案件所需的第一个值,其余的则是其他情况。
我建议建立一个适合您需求的结构,例如:
在这种情况下,您确保数据有效,并且可以给您的登录名称,以反映您的价值所代表的内容。在此示例中,我给了他们虚拟名称,但是您应该尝试制作与您的业务相关的东西。
可以使用这样的类(更改名称只是为了说明方法命名如何记录您的代码):
您应该首先尝试了解数据架构代表的内容并构建有用的API,以隐藏实现实现以更好地反映您的业务。
If I understand correctly your issue: you have a first value that you need for a case, and the rest for another case.
I would recommend building a structure that fits your needs, something like this:
In this case, you make sure your data is valid, and you can give your accessors names that reflects what you those value are representing. In this example, I gave them dummy names, but you should try to make something that is relevant to your business.
Such a class could be used this way (changed names just to illustrate how method naming can document your code):
You should first try to understand what your datastructure represents and build a useful api that hide the implementation to better reflect your business.