Изменение количества итераций в цикле for
у меня есть такой код:
loopcount = 3
for i in range(1, loopcount)
somestring = '7'
newcount = int(somestring)
loopcount = newcount
Итак, я хочу изменить диапазон для "внутри" цикла.
Я написал этот код, ожидая, что диапазон цикла for изменится на (1,7) во время первого цикла, но этого не произошло.
вместо этого, независимо от того, какое число я поставил, он работает только 2 раза. (Я хочу 6 раз.. в этом случае)
Я проверил значение с помощью печати, как это:
loopcount = 3
for i in range(1, loopcount)
print loopcount
somestring = '7'
newcount = int(somestring)
loopcount = newcount
print loopcount
#output:
3
7
7
7
что не так? число были изменены.
где мое мышление неправильно?
8 ответов
диапазон создается на основе значения loopcount
во время его вызова-все, что происходит с loopcount после этого, не имеет значения. То, что вы, вероятно, хотите, это заявление while:
loopcount = 3
i = 1
while i < loopcount:
somestring = '7'
loopcount = int(somestring)
i += 1
на while
проверяет, что условие i < loopcount
является true, и если true, если запускает операторы, которые он содержит. В этом случае при каждом проходе через петлю i увеличивается на 1. Поскольку loopcount установлен в 7 в первый раз, цикл будет выполняться шесть раз, для i = 1,2,3,4,5 и 6.
как только условие ложно, когда i = 7
, цикл while перестает выполняться.
(Я не знаю, каков ваш фактический вариант использования, но вам, возможно, не нужно назначать newcount, поэтому я удалил это).
С range()
docstring:
range ([start,] stop [, step]) - > список целых чисел
возвращает список, содержащий арифметическую прогрессию чисел. диапазон (i, j) возвращает [i, i+1, i+2, ..., j-1]; start (!) по умолчанию 0. Когда шаг задан, он указывает приращение (или уменьшение). Например, range (4) возвращает [0, 1, 2, 3]. Конечная точка опущена! Это точно действительные индексы для списка из 4 элементы.
и range(1, 10)
, например, возвращает список типа: [1,2,3,4,5,6,7,8,9]
, таким образом, ваш код в основном делаю:
loopcount = 3
for i in [1, 2]:
somestring = '7'
newcount = int(somestring)
loopcount = newcount
когда for
цикл "инициализирован", список создается range()
.
на while-loop ответ user802500 вероятно, будет лучшим решением вашей реальной проблемы; однако, я думаю, что вопрос как просил есть интересный и поучительный ответ.
результат range () вызовов-это список последовательных значений. Цикл for повторяет этот список, пока он не будет исчерпан.
вот ключевой момент:вы можете мутировать список во время итерация.
>>> loopcount = 3
>>> r = range(1, loopcount)
>>> for i in r:
somestring = '7'
newcount = int(somestring)
del r[newcount:]
практическим использованием этой функции является итерация по задачам в списке задач и позволяет некоторым задачам генерировать новые задачи:
for task in tasklist:
newtask = do(task)
if newtask:
tasklist.append(newtask)
чтобы конкретно решить вопрос "Как изменить границы диапазона", вы можете воспользоваться отправка метод для генератора:
def adjustable_range(start, stop=None, step=None):
if stop is None:
start, stop = 0, start
if step is None: step = 1
i = start
while i < stop:
change_bound = (yield i)
if change_bound is None:
i += step
else:
stop = change_bound
использование:
myrange = adjustable_range(10)
for i in myrange:
if some_condition:
myrange.send(20) #generator is now bounded at 20
похоже, что ваша предпосылка заключается в том, что у вас есть число по умолчанию, когда цикл должен выполняться, но случайное условие, где оно отличается. Может быть, лучше использовать цикл while, но независимо от этого вы можете просто сделать:
if i == some_calculated_threshold:
break
чтобы выйти из цикла вместо этого.
вы можете увеличить количество итераций после того, как был установлен, но вы можете выйти досрочно, тем самым уменьшая количество повторов:
for i in xrange(1, 7):
if i == 2:
break
вот более полная реализация adjustable_range
функция, предоставленная Джоэлом Корнеттом.
def adjustable_range(start, stop=None, step=None):
if not isinstance(start, int):
raise TypeError('start')
if stop is None:
start, stop = 0, start
elif not isinstance(stop, int):
raise TypeError('stop')
direction = stop - start
positive, negative = direction > 0, direction < 0
if step is None:
step = +1 if positive else -1
else:
if not isinstance(step, int):
raise TypeError('step')
if positive and step < 0 or negative and step > 0:
raise ValueError('step')
if direction:
valid = (lambda a, b: a < b) if positive else (lambda a, b: a > b)
while valid(start, stop):
message = yield start
if message is not None:
if not isinstance(message, int):
raise ValueError('message')
stop = message
start += step