Python 中从 1 到无穷大循环

问题描述 投票:0回答:9

在 C 语言中,我会这样做:

int i;
for (i = 0;; i++)
  if (thereIsAReasonToBreak(i))
    break;

如何在 Python 中实现类似的功能?

python loops
9个回答
181
投票

使用

itertools.count

import itertools
for i in itertools.count(start=1):
    if there_is_a_reason_to_break(i):
        break

在 Python 2 中,

range()
xrange()
仅限于
sys.maxsize
。在 Python 3 中
range()
可以更高,但不会达到无穷大:

import sys
for i in range(sys.maxsize**10):  # you could go even higher if you really want
    if there_is_a_reason_to_break(i):
        break

所以最好使用

count()


27
投票
def to_infinity():
    index = 0
    while True:
        yield index
        index += 1

for i in to_infinity():
    if i > 10:
        break

18
投票

最简单最好的:

i = 0
while not there_is_reason_to_break(i):
    # some code here
    i += 1

选择与 Python 中的 C 代码最接近的类比可能很诱人:

from itertools import count

for i in count():
    if thereIsAReasonToBreak(i):
        break

但要注意,修改

i
不会像在C中那样影响循环的流程。因此,使用
while
循环实际上是将C代码移植到Python的更合适的选择。


6
投票

如果您想使用

for
循环,可以组合内置函数
iter
(另请参阅这个答案)和
enumerate
来实现具有计数器的无限
for
循环。我们使用
iter
创建一个无限迭代器,并且
enumerate
提供计数循环变量。默认情况下,起始值为零,但您可以使用
start
参数设置不同的起始值。

for i, _ in enumerate(iter(bool, True), start=1):
    input(i)

哪个打印:

1
2
3
4
5
...

5
投票

重申thg435的评论:

from itertools import takewhile, count

def thereIsAReasonToContinue(i):
    return not thereIsAReasonToBreak(i)

for i in takewhile(thereIsAReasonToContinue, count()):
    pass # or something else

或者更简洁地说:

from itertools import takewhile, count

for i in takewhile(lambda x : not thereIsAReasonToBreak(x), count()):
    pass # or something else

takewhile
模仿“行为良好”的 C for 循环:你有一个延续条件,但你有一个生成器而不是任意表达式。您可以在 C for 循环中执行一些“行为不当”的操作,例如修改循环体中的
i
。如果生成器是某个局部变量
takewhile
的闭包,那么您也可以使用
i
来模仿它们。在某种程度上,定义该闭包使得您正在做一些可能与您的控制结构混淆的事情变得特别明显。


2
投票
def infinity():
    i=0
    while True:
        i+=1
        yield i


for i in infinity():
    if there_is_a_reason_to_break(i):
        break

2
投票

如果你在 C 中这样做,那么你的判断就和在 Python 中一样模糊:-)

对于在每次迭代开始时通过简单条件检查退出的循环,更常见(在我看来更清晰)是在循环构造本身中执行此操作。换句话说,类似(如果循环结束后需要

i
):

int i = 0;
while (! thereIsAReasonToBreak(i)) {
    // do something
    i++;
}

或(如果

i
的范围可以限定为 just 循环):

for (int i = 0; ! thereIsAReasonToBreak(i); ++i) {
    // do something
}

这将转化为 Python 的等价物:

i = 0
while not there_is_a_reason_to_break(i):
    # do something
    i += 1

只有当您需要在循环的“中间”某个地方退出时(或者如果您的条件足够复杂以至于会使循环语句的可读性大大降低),您才需要担心中断。 当您的潜在退出是循环的

start

处的一个简单退出时(正如此处所示),通常最好将退出编码到循环本身中。


2
投票


0
投票
for

而不是

while
以及更改
variable
的值来影响循环的功能,这里有一个面向对象的解决方案:
class Count:
    def __init__(self, start):
        self.count = start - 1

    def increment(self):
        self.count += 1

    def set(self, number):
        self.count = number - 1

# Since __next__ method directly increments, to balance that `-1` is used in Count class.

class InfiniteIter:
    def __init__(self, start):
        self.count = Count(start)
    
    def __iter__(self):
        return self

    def __next__(self):
        self.count.increment()
        return self.count
    
for i in InfiniteIter(1):
    print(i.count)

    if i.count == 5:
        i.set(10)

    input() # for testing purpose

说明:

  • for

    循环在完成每次迭代后调用

    __next__
    方法,返回一个
    Count
    对象。
    
    

  • Count

    对象有一个方法

    set
    用于设置
    count
    属性的值。
    
    

  • 由于
  • __next__

    方法直接递增,以平衡

    -1
    在 Count 类中使用。
    
    

  • Count

    对象

    count
    属性可用于访问值。 (
    也可用于设置值,但由于第3点,该数字已为-1

© www.soinside.com 2019 - 2024. All rights reserved.