简体   繁体   English

如何在python的while循环语句中使用迭代器

[英]how to use iterator in while loop statement in python

Is it possible to use a generator or iterator in a while loop in Python?是否可以在 Python 的 while 循环中使用生成器或迭代器? For example, something like:例如,类似于:

i = iter(range(10))
while next(i):
    # your code

The point of this would be to build iteration into the while loop statement, making it similar to a for loop, with the difference being that you can now additional logic into the while statement:这样做的目的是将迭代构建到 while 循环语句中,使其类似于 for 循环,不同之处在于您现在可以在 while 语句中添加额外的逻辑:

i = iter(range(10))
while next(i) and {some other logic}:
    # your code

It then becomes a nice for loop/while loop hybrid.然后它成为一个很好的 for 循环/while 循环混合。

Does anyone know how to do this?有谁知道如何做到这一点?

In Python < 3.8 you can use itertools.takewhile :在 Python < 3.8 中,您可以使用itertools.takewhile

from itertools import takewhile

i = iter(range(10))
for x in takewhile({some logic}, i):
    # do stuff

"Some logic" here would be a 1-arg callable receciving whatever next(i) yields:这里的“一些逻辑”将是一个 1-arg 可调用的接收next(i)产生的任何内容:

for x in takewhile(lambda e: 5 > e, i):
    print(x)
0
1
2
3
4

In Python >= 3.8, you can do the following, using assignment expressions :在 Python >= 3.8 中,您可以使用赋值表达式执行以下操作:

i = iter(range(10))
while (x := next(i, None)) is not None and x < 5:
    print(x)

There are two problems with while next(i): while next(i):有两个问题while next(i):

  1. Unlike a for loop, the while loop will not catch the StopIteration exception that is raised if there is no next value;for循环不同, while循环不会捕获在没有next值时引发的StopIteration异常; you could use next(i, None) to return a "falsey" value in that case, but then the while loop will also stop whenever the iterator returns an actual falsey value在这种情况下,您可以使用next(i, None)返回“falsey”值,但是只要迭代器返回实际的 falsey 值, while循环也会停止
  2. The value returned by next will be consumed and no longer available in the loop's body. next返回的值将被消耗并且不再在循环体中可用。 (In Python 3.8+, that could be solved with an assignment expression, see other answer.) (在 Python 3.8+ 中,这可以通过赋值表达式解决,请参阅其他答案。)

Instead, you could use a for loop with itertools.takewhile , testing the current element from the iterable, or just any other condition.相反,您可以将for循环与itertools.takewhile ,从可迭代对象或任何其他条件测试当前元素。 This will loop until either the iterable is exhausted, or the condition evaluates to false.这将循环直到迭代耗尽,或者条件评估为假。

from itertools import takewhile
i = iter(range(10))
r = 0
for x in takewhile(lambda x: r < 10, i):
    print("using", x)
    r += x
print("result", r)

Output:输出:

using 0
...
using 4
result 10

You just need to arrange for your iterator to return a false-like value when it expires.您只需要安排您的迭代器在到期时返回一个类似 false 的值。 Eg, if we reverse the range so that it counts down to 0:例如,如果我们反转range以使其倒计时为 0:

>>> i = iter(range(5, -1, -1))
>>> while val := next(i):
...     print('doing something here with value', val)
...

This will result in:这将导致:

doing something here with value 5
doing something here with value 4
doing something here with value 3
doing something here with value 2
doing something here with value 1
a = iter(range(10))

try:
    next(a)
    while True:
        print(next(a))
except StopIteration:
    print("Stop iteration")

You can do你可以做

    a = iter(range(10))

    try:
        a.next()
        while True and {True or False logic}:
            print("Bonjour")
            a.next()
    except StopIteration:
        print("a.next() Stop iteration")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM