Итерируйте определенное количество раз, не сохраняя номер итерации где-либо
Мне было интересно, возможно ли выполнить определенное количество операций, не сохраняя где-либо номер итерации цикла.
Например, допустим, я хочу напечатать два сообщения "hello"
на консоль. Прямо сейчас я знаю, что могу сделать:
for i in range(2):
print "hello"
но тогда переменная i
будет принимать значения 0
и 1
(которые мне на самом деле не нужны). Есть ли способ достичь того же самого, не сохраняя эти нежелательные значения в любом месте?
Ответы
Ответ 1
Идиома (разделяемая довольно многими другими языками) для неиспользуемой переменной - это одно подчеркивание _
. Анализаторы кода обычно не будут жаловаться на то, что _
не используется, и программисты мгновенно узнают об этом ярлыке для i_dont_care_wtf_you_put_here
. Невозможно выполнить итерацию без переменной item - как указывает Zen of Python, "специальные случаи не являются достаточно сложными, чтобы нарушать правила".
Ответ 2
exec 'print "hello";' * 2
должен работать, но мне стыдно, что я думал об этом.
Обновление: Просто подумал о другом:
for _ in " "*10: print "hello"
Ответ 3
Ну, я думаю, что прелюс, который вы предоставили в вопросе, примерно так же хорош, как и он, но я хочу указать, что неиспользуемые переменные, которые должны быть назначены, могут быть назначены переменной с именем _
, конвенцией для "отбрасывания" присвоенного значения. Хотя ссылка _
будет содержать значение, которое вы ему дали, кодовые линтеры и другие разработчики поймут, что вы не используете эту ссылку. Итак, вот пример:
for _ in range(2):
print('Hello')
Ответ 4
Другие обращались к неспособности полностью избежать итерационной переменной в цикле for
, но есть варианты, чтобы уменьшить работу до минимума. В конце концов, range
должен сгенерировать целую кучу чисел, что потребует небольшого количества работы; если вы хотите избежать даже этого, вы можете использовать itertools.repeat
, чтобы снова и снова возвращать одно и то же (игнорируемое) значение, что не требует создания/извлечения различных объектов:
from itertools import repeat
for _ in repeat(None, 200): # Runs the loop 200 times
...
В микробенчмарках это будет работать быстрее, чем в for _ in range(200):
, но если тело цикла выполняет значимую работу, это капля в море. И в отличие от умножения некоторой анонимной последовательности для итерируемого цикла, repeat
имеет только тривиальные затраты на установку, при этом никакие накладные расходы памяти не зависят от длины.
Ответ 5
Хотя я полностью согласен с ответом delnan, это не невозможно:
loop = range(NUM_ITERATIONS+1)
while loop.pop():
do_stuff()
Обратите внимание, однако, что это не будет работать для произвольного списка: если первое значение в списке (последнее выскользнуло) не оценивается до False
, вы получите еще одну итерацию и исключение на следующем проходе: IndexError: pop from empty list
. Кроме того, после цикла ваш список (loop
) будет пуст.
Просто ради любопытства.;)
Ответ 6
Извините, но для того, чтобы перебирать что-либо на любом языке, включая Python и английский, индекс должен быть сохранен. Будь то в переменной или нет. Поиск способа скрыть тот факт, что python внутренне отслеживает цикл for, не изменит того факта, что он есть. Я бы рекомендовал оставить его как есть.
Ответ 7
Это будет печатать "привет" 3 раза без сохранения i
...
[print('hello') for i in range(3)]
Ответ 8
Вы можете просто сделать
print 2*'hello'
Ответ 9
for word in ['hello'] * 2:
print word
Это не идиоматический Python, но это не то, что вы пытаетесь сделать.
Ответ 10
Оказывается, что использование манекена * (начальное слово является фиктивным) в качестве переменной выполняет тот же трюк, что и _. Но вы не связываетесь с уже определенной, а иногда и используемой переменной или функцией.