Страницы

Поиск по вопросам

среда, 29 января 2020 г.

Можно ли итерировать параметр цикла 'for' внутри цикла?

#python #for #iterator


понятно, что лобовой вариант не проходит:

for i in range(5):
    print(i)
    i=4


не проходит.     На печать выйдет:

0
1
2
3
4


Однако вопрос остается - можно как-то манипулировать i так, чтобыцикл "воспринимал"
желаемые изменения?
Или в этом случае  -  только цикл while?
Я имею ввиду попытки типа:

r5 = range(5)
for i in r5:
    print(i)
    for i in range(4):
        r5.__iter__()


но так оно не работает (
-----------------------------------------------ЗАРАБОТАЛО--после ответа @Александр:

d = [2,7,9,10,11,15,19,20,21,30,31]
m_d = [[x,0] for x in d]

mark = 0
_ = iter(range(len(m_d)-1))
for i in _:   
    while (m_d[i+1][0]-m_d[i][0] <2) and (i


Ответы

Ответ 1



Если вы всё-таки упорно не хотите использовать while и вам нужно просто пропустить часть значений, и вы это хотите сделать именно с помощью манипулирования объектом после in, то можно сделать так: r100 = iter(range(100)) for i in r100: print(i) for j in range(3): next(r100) Этот цикл пройдётся по числам до 100, но после каждого напечатанного числа будет пропускать следующие три. Но всё таки гораздо правильнее не хачить итераторы, а сделать например так: skip = 0 for i in range(100): if skip: skip -= 1 else: print(i) skip = 3 Этот код сделает то же самое, но его проще читать, и меньше вероятность, что он станет причиной трудноотлавливаемой ошибки.

Ответ 2



Давайте сформулируем задачу. Разбить список на группы, так, чтобы все последовательные числа попали в одну группу [[2], [7], [9,10,11], [15], [19,20,21], [30,31]] Промаркировать все числа в каждой группе номером соответствующей группы и слить обратно в список [(0,[2]), (1,[7]), (2,[9,10,11]), (3,[15]), (4,[19,20,21]), (5,[30,31])] [[2,0], [7,1], [9,2], [10,2], [11,2], [15,3], [19,4], [20,4], [21,4], [30,5], [31,5]] Группировать будем используя такую хитрость: Из каждого элемента вычтем его индекс, полученный результат будет ключом группы [2-0, 7-1, 9-2, 10-3, 11-4, 15-5, 19-6, 20-7, 21-8, 30-9, 31-10] [2, 6, 7,7,7, 10, 13,13,13, 21,21] Задача целиком решается так (правда группировать будем индексы элементов, а не сами элементы): from itertools import groupby def markgroups(elems): def getkey(idx): "По номеру элемента возвращает ключ его группы" return elems[idx] - idx groups = (group for _, group in groupby(range(len(elems)), key=getkey)) return [[elems[idx], group_idx] for group_idx, group in enumerate(groups) for idx in group] print(markgroups([2, 7, 9, 10, 11, 15, 19, 20, 21, 30, 31])) Не стану утверждать, что это решение очень легко понять новичку, но новичок состояние не перманентное - пара недель практики, и все станет понятно и естественно. Однако оцените, несколько просто можно сформулировать задачу, и также просто описать ее решение естественным языком. UPD: Обновил решение, чтобы оно не создавало промежуточные списки. Хотел сделать так изначально, но решил что со списками будет проще понять, как это работает. Тест производительности на списке из ~800000 элементов (примерно каждый пятый пропущен): inplace: 0.4143 s markgroups: 0.2756 s https://ideone.com/Kv3F8U

Ответ 3



Нет, нельзя. Суть цикла for в том, что он итерируется по объекту идущему после in и на каждом шаге присваивает очередное значение переменной, идущей до in. То есть что бы вы не сделали внутри итерации, вначале следующей переменная всё равно получит очередное значение. Так что да, чтобы изменения в переменной сохранялись, нужно использовать цикл while.

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

Отправить комментарий