更改for循环中的迭代次数

时间:2012-08-10 16:21:02

标签: python loops for-loop range

我有这样的代码:

loopcount = 3
for i in range(1, loopcount)
   somestring = '7'
   newcount = int(somestring)
   loopcount = newcount

所以我想要的是修改for循环中'for'的范围。

我编写了这段代码,期望for循环的范围在第一次循环期间会变为(1,7),但是没有发生。

相反,无论我输入什么号码,它只运行2次。 (我想要6次......在这种情况下)

我使用print检查了这个值:

    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 个答案:

答案 0 :(得分:28)

范围是在调用时基于loopcount的值创建的 - 之后发生循环计数的任何事情都无关紧要。你可能想要的是一个while语句:

loopcount = 3
i = 1
while i < loopcount:
    somestring = '7'
    loopcount = int(somestring)
    i += 1

while测试条件i < loopcount为真,如果为真,则运行它包含的语句。在这种情况下,在每次通过循环时,i增加1.由于loopcount在第一次设置为7时,循环将运行六次,因为i = 1,2,3,4,5和6 。

一旦条件为假,当i = 7时,while循环停止运行。

(我不知道你的实际用例是什么,但你可能不需要分配newcount,所以我删除了它)。

答案 1 :(得分:11)

来自range() docstring:

  

范围([start,] stop [,step]) - &gt;整数列表

     

返回包含整数算术级数的列表。   range(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()创建。

答案 2 :(得分:3)

user802500 提供的 while-loop 答案可能是您实际问题的最佳解决方案;但是,我认为问题的问题有一个有趣且有启发性的答案。

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)

答案 3 :(得分:2)

for - 循环中评估range()函数时,它会生成一系列值(即列表),用于迭代。

range()为此使用loopcount的值。但是,一旦生成了那个序列,你在里面循环中没有任何东西会改变那个列表,即即使你后来更改loopcount,原始列表也是如此将保持不变=&gt;迭代次数将保持不变。

在你的情况下:

loopcount = 3
for i in range(1, loopcount):

变为

for i in [1, 2]:

所以你的循环迭代两次,因为你在循环中有2个print语句得到4行输出。请注意,您打印的loopcount值最初为3,但随后设置(并重置)为7.

如果您希望能够动态更改迭代次数,请考虑使用while - 循环。当然,您可以使用break语句提前停止/退出任何循环。

此外,

   somestring = '7'
   newcount = int(somestring)

可以简化为

   newcount = 7

答案 4 :(得分:2)

要专门解决“如何更改范围界限”这一问题,您可以利用send method for a generator

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

答案 5 :(得分:1)

看起来你的前提是你有一个默认的循环应该执行的次数,但偶尔的条件是不同的。使用while循环可能更好,但无论你做什么都可以:

if i == some_calculated_threshold:
    break

转而退出循环。

答案 6 :(得分:0)

一旦设置了范围,就不能增加迭代次数,但是你可以提前分解,从而减少迭代次数:

for i in xrange(1, 7):
   if i == 2:
       break

答案 7 :(得分:0)

以下是Joel Cornett提供的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