Для цикла с несколькими операторами приращения в Python

#python #c #for-loop

Вопрос:

В C for циклы могут иметь несколько операторов «приращения». Например:

 int j;
unsigned int r;

r  = 4;  // in reality, a non-trivial initialization

for (j = 0; j < 1000; j  , r  )  {
    if (r == 8)
        r = 0;

    printf("j = %d, r = %un", j, r);

    // ... do some work, including continue statements

}
 

В приведенном выше цикле j и r увеличиваются одновременно на каждой итерации цикла.

Теперь я задаюсь вопросом, как я могу повторить то же самое в Python. До сих пор я нашел следующее решение, которое не так элегантно.

 r = 4 # actually a complicated initialization

r = r - 1

for j in range(1000):
    r = r   1
    if r == 8:
        r = 0
     # the rest of the loop
 

Версия Python явно уродливее (особенно из-за уменьшения r на 1 перед началом цикла).

Есть ли более приятный способ сделать это?

Комментарии:

1. используйте (j 4) % 8 вместо r

2. j , r на самом деле это один оператор, использующий оператор запятой. И в целом это затрудняет чтение кода, а не облегчает его… и есть проблема побочных эффектов. Правильно написанные циклы имеют один итератор цикла. Тогда у вас могут быть и другие переменные, которые также изменяют значение, но вы не должны смешивать их с итератором цикла — это только приведет к путанице. Лично я бы написал ваш цикл следующим образом: for (int j = 0; j < 1000; j ) { ... r ; } .

3. @NicholasHunter Я показал только MWE. На самом деле r не всегда инициализируется до 4. Но он увеличивается на единицу в соответствии с j .

4. @Лундин, я думал об этом решении. Проблема в том, что мне также нужно повторять r перед каждым continue оператором внутри тела цикла. (Очевидно, что это относится как к версиям Python, так и к C).

5. Я не уверен, что есть более простой способ сделать это, потому j , r что это происходит только после первой итерации, поэтому обычно в Python вы эмулируете это, увеличивая в конце тела цикла и перед каждым break и continue . Вы могли бы поместить его в начало тела цикла в an if j !=0: #dostuff , но это бесполезная проверка после первой итерации.

Ответ №1:

Есть какой-то способ выполнить параллельную итерацию :

 from itertools import product
min_i, min_j = 1, 2
max_i, max_j = 3, 4
for i, j in product(iter(range(min_i, max_i   1)),iter(range(min_j, max_j   1))):
    print(i,j)
 

Результат :

 1 2
1 3
1 4
2 2
2 3
2 4
3 2
3 3
3 4
 

Если вы имеете в виду что-то другое, дайте мне знать. Тогда я исправлю свой ответ.