В C я бы сделал следующее:
int i;
for (i = 0;; i++)
if (thereIsAReasonToBreak(i))
break;
Как я могу добиться чего-то подобного в Python?
В C я бы сделал следующее:
int i;
for (i = 0;; i++)
if (thereIsAReasonToBreak(i))
break;
Как я могу добиться чего-то подобного в Python?
Использование itertools.count
:
import itertools
for i in itertools.count():
if there_is_a_reason_to_break(i):
break
В Python2 xrange()
ограничен sys.maxint, чего может быть достаточно для практических целей:
import sys
for i in xrange(sys.maxint):
if there_is_a_reason_to_break(i):
break
В Python3 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()
.
def to_infinity():
index=0
while 1:
yield index
index += 1
for i in to_infinity():
if i > 10:break
Самый простой и лучший:
i = 0
while not there_is_reason_to_break(i):
# some code here
i += 1
Возможно, возникает соблазн выбрать ближайшую аналогию с C-кодом, который возможен в Python:
from itertools import count
for i in count():
if thereIsAReasonToBreak(i):
break
Но будьте осторожны, модификация i
не будет влиять на поток цикла, как это было бы в C. Поэтому использование цикла while
на самом деле является более подходящим выбором для переноса этого кода на C на Python.
Повторяя комментарий 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: у вас есть условие продолжения, но вместо произвольного выражения у вас есть генератор. Есть вещи, которые вы можете сделать в цикле C, которые "плохо себя ведут", например, изменение i
в теле цикла. Можно также имитировать их с помощью takewhile
, если генератор является замыканием над некоторой локальной переменной i
, с которой вы тогда сталкиваетесь. В некотором смысле, определение этого закрытия делает особенно очевидным, что вы делаете что-то потенциально запутанное с вашей структурой управления.
Если вы делаете это на C, тогда ваше суждение будет таким же облачным, как и в Python: -)
Лучший способ C:
int i = 0;
while (! thereIsAReasonToBreak (i)) {
// do something
i++;
}
или
int i; // *may* be better inside the for statement to localise scope
for (i = 0; ! thereIsAReasonToBreak (i); i++) {
// do something
}
Это переведет на Python:
i = 0
while not thereIsAReasonToBreak (i):
# do something
i += 1
Только если вам нужно выйти из середины цикла, вам нужно будет беспокоиться о нарушении. Если ваш потенциальный выход находится в начале цикла (как представляется, здесь), обычно лучше кодировать выход в сам цикл.
Это работает для всех версий python:
m=1
for i in range(m):
#action here
m+=1
Простой и понятный.
Вероятно, лучшим решением для этого является использование цикла while:
i=1
while True:
if condition:
break
...........rest code
i+=1
Если вам нужно указать предпочитаемый размер шага (например, с диапазоном) и вы предпочитаете не импортировать внешний пакет (например, itertools),
def infn(start=0, step_size=1):
"""Infinitely generate ascending numbers"""
while True:
yield start
start += step_size
for n in infn():
print(n)
a = 1
while a:
if a == Thereisareasontobreak(a):
break
a += 1
while 1==1:
if want_to_break==yes:
break
else:
# whatever you want to loop to infinity
Этот цикл с бесконечным ходом.
Вы также можете сделать следующее:
list=[0] for x in list:
list.append(x+1)
print x
Это приведет к бесконечному for loop
.