для циклов в Python - как изменить я внутри цикла - PullRequest
0 голосов
/ 04 июня 2018

Этот код был написан на Python 3.6 в Jupyter Notebooks.В других языках я почти уверен, что построил циклы, которые выглядели так:

endRw=5
lenDF=100   # 1160

for i in range(0, lenDF):
    print("i: ", i)
    endIndx = i + endRw
    if endIndx > lenDF:
                endIndx = lenDF

    print("Range to use: ", i, ":", endIndx)
    # this line is a mockup for an index that is built and used
    # in the real code to do something to a pandas DF

    i = endIndx
    print("i at end of loop", i)

В тестировании, однако, i не сбрасывается до endIndx, и поэтому цикл не создает требуемый индексзначения.

Я смог решить эту проблему и получить то, что искал, построив цикл while, подобный следующему:

endRw=5
lenDF=97   # 1160
i = 0
while i < lenDF:
    print("i: ", i)
    endIndx = i + endRw
    if endIndx > lenDF:
                endIndx = lenDF

    print("Range to use: ", i, ":", endIndx)
    # this line is a mockup for an index that is built and used
    # in the real code to do something to a pandas DF

    i = endIndx
    print("i at end of loop: ", i)

Вопрос: есть ли способ изменить * 1011?* внутри цикла for в python?Есть ли способ сделать то, что я сделал с циклом while, используя цикл for в Python?

Решил проблему с while, но просто любопытно:

Ответы [ 5 ]

0 голосов
/ 05 июня 2018

Вы всегда можете установить значение i в цикле for.Проблема в том, что ваш оператор значения настройки находится перед неявным оператором значения цикла for и покрывается последним.Вы не можете изменить правило, чтобы сделать последнее утверждение бесполезным.Вы не должны делать это, даже если можете.Просто измените на использование правильной условной переменной.

0 голосов
/ 05 июня 2018

В буквальном смысле исходный вопрос:

  • @ Tobias_k дает хорошее объяснение того, когда использовать циклы while против for, и вариант использования этого вопросаподходит while лучше (по крайней мере, для Python).Вкратце: вы не можете напрямую изменить i в for i in из-за того, как этот код работает под прикрытием в Python.Поэтому while следует использовать для случая, когда вам нужно изменить свой счетчик внутри цикла (на Python).
  • @ tdelaney дает хороший ответ с точки зрения рефакторинга кода с использованием Python forцикл с учетом поведения Python ( принятый ответ на этот вопрос).
  • @ PaulPanzer предоставляет понятия , которые, хотя и слишком сложны, полезны для изучения студентаминовые концепции;но ответ решает проблему цикла for, используя цикл while внутри итератора и вызывая его в цикле for.

Несмотря на это, исследованные концепции играют на пользуиз yield и итераторы заслуживают изучения.Если мы возьмем эти концепции и попытаемся переписать исходный код, чтобы использовать их, это будет выглядеть так:

def jumpable_range(start, stop):
    i = start
    while i <= stop:
        j = yield i
        i = i + 1 if j is None else j

endRw=5
lenDF=97   # 1160

Q = jumpable_range(0,lenDF)
for i in Q:
    print("i: ", i)
    endIndx = i + endRw
    if endIndx > lenDF:
                endIndx = lenDF

    if i == endIndx: break

    print("Range to use: ", i, ":", endIndx)
    # this line is a mockup for an index that is built and used
    # in the real code to do something to a pandas DF

    i = Q.send(endIndx-1)
    print("i at end of loop", i)
0 голосов
/ 04 июня 2018

Этот ответ вряд ли будет полезен, но поскольку вам было просто любопытно: я думаю, самое близкое к тому, что вы хотите сделать, это использовать генератор и его метод send:

>>> def jumpable_range(start, stop):
...     i = start
...     while i <= stop:
...         j = yield i
...         i = i + 1 if j is None else j
... 
>>> R = jumpable_range(2, 10)
>>> 
>>> for i in R:
...     if i==5:
...         i = R.send(8)
...     print(i)
... 
2
3
4
8
9
10
>>> 
0 голосов
/ 04 июня 2018
Циклы

for работают с итерациями.В for i in range(0, lenDF), i присваивается следующее значение в диапазоне в каждом цикле цикла независимо от того, как оно используется в цикле.Тогда возникает вопрос: есть ли чистый способ написать итерацию, которая делает то, что вы хотите.В этом случае все, что вам нужно, это продвинуться на фиксированный шаг и отрегулировать конечную длину шага, чтобы учесть конец данных.

endRw=5
lenDF=97   # 1160

for i in range(0, lenDF, endRw):
    endIndx = min(i+endRw, lenDF)
    print("Range to use: ", i, ":", endIndx)
0 голосов
/ 04 июня 2018

Вы можете изменить переменную цикла в цикле for, проблема в том, что циклы for в Python не похожи на циклы for "старого стиля", например, в Java, но болеекак "новый стиль" for-each циклы.

В Python for i in range(0, 10): ведет себя не как for (int i = 0; i < 10; i++) {, а как for (int i : new int[] {0, 1, ..., 10}}.

То есть в каждой итерациицикл, глава цикла не будет изменять переменную цикла (например, увеличивать ее), но назначит ей новое значение , то есть следующее значение из данной итерируемой (a range в вашем случае).Таким образом, любые изменения, которые вы сделали в предыдущей итерации, будут перезаписаны.

Если вы хотите зациклить известное количество итераций или для каждого элемента в итерируемой, используйте цикл for, но если вы хотитецикл до тех пор, пока не будет выполнено определенное условие (больше не выполняется), как в вашем случае используйте while.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...