22

次のようなコードがあります。

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

だから私が欲しいのは、ループの「内側」の範囲を変更することです。

最初のループで 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

なにが問題ですか?番号が変更されました。

私の考えはどこが間違っていますか?

4

8 に答える 8

39

範囲は、呼び出された時点の の値に基づいて作成されますloopcount。後で loopcount に何が起こっても関係ありません。おそらくあなたが望むのはwhileステートメントです:

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

while、条件が true であることをテストし、i < loopcounttrue の場合は、それに含まれるステートメントを実行します。この場合、ループを通過するたびに、i が 1 ずつ増加します。最初のループでは loopcount が 7 に設定されているため、i = 1,2,3,4,5 および 6 の場合、ループは 6 回実行されます。 .

条件が false になるi = 7と、while ループの実行が停止します。

(実際のユースケースはわかりませんが、 newcount を割り当てる必要はないかもしれないので、削除しました)。

于 2012-08-10T16:26:22.040 に答える
11

range()docstringから:

range([start,] stop[, step]) -> 整数のリスト

整数の算術数列を含むリストを返します。range(i, j) は [i, i+1, i+2, ..., j-1] を返します。start (!) のデフォルトは 0 です。step を指定すると、インクリメント (またはデクリメント) を指定します。たとえば、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()

于 2012-08-10T16:23:46.347 に答える
5

user802500によって与えられたwhile-loopの回答は、実際の問題に対する最良の解決策である可能性があります。ただし、尋ねられた質問には、興味深く有益な答えがあると思います。

range()呼び出しの結果は、連続した値のリストです。for ループは、使い果たされるまでそのリストを繰り返します。

重要な点は次のとおり です。反復中にリストを変更することが許可されています

>>> loopcount = 3
>>> r = range(1, loopcount)
>>> for i in r:
        somestring = '7'
        newcount = int(somestring)
        del r[newcount:]

この機能の実用的な使い方は、todo リスト内のタスクを反復処理し、一部のタスクが新しい todo を生成できるようにすることです。

for task in tasklist:
    newtask = do(task)
    if newtask:
        tasklist.append(newtask)
于 2012-08-10T18:58:11.247 に答える
2

「範囲の境界を変更するにはどうすればよいですか」という質問に具体的に対処するために、ジェネレーターのsendメソッドを利用できます。

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
于 2012-08-10T16:35:21.377 に答える
2

-loopでrange()関数が評価さforれると、反復処理に使用される一連の値 (つまり、リスト) が生成されます。

range()これには の値を使用しますloopcount。ただし、そのシーケンスが生成されると、ループで何をしてもそのリストは変更されません。つまり、後で変更しても、元のリストは同じままです => 反復回数は同じままです。loopcount

あなたの場合:

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

になる

for i in [1, 2]:

printしたがって、ループに 2 つのステートメントがあるため、ループは 2 回繰り返され、4 行の出力が得られます。loopcount最初は 3の値を出力していますが、その後 7 に設定 (およびリセット) されることに注意してください。

反復回数を動的に変更できるようにしたい場合は、while代わりに -loop を使用することを検討してください。もちろん、breakステートメントを使用して、いつでもループを早期に停止/終了できます。

また、

   somestring = '7'
   newcount = int(somestring)

に単純化することができます

   newcount = 7
于 2012-08-10T16:24:06.820 に答える
1

あなたの前提は、ループを実行するデフォルトの回数があるが、それが異なる場合があるということです。代わりに while ループを使用する方が良いかもしれませんが、とにかく次のことを実行できます。

if i == some_calculated_threshold:
    break

代わりにループから脱落します。

于 2012-08-10T16:27:11.753 に答える
0

adjustable_rangeJoelCornettが提供する関数のより完全な実装を次に示します。

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
于 2012-08-10T17:13:49.393 に答える
0

範囲が設定されると、反復回数を増やすことはできませんが、早期に中断して反復回数を減らすことはできます。

for i in xrange(1, 7):
   if i == 2:
       break
于 2012-08-10T16:29:15.627 に答える