Можно ли сделать следующее без i
?
for i in range(some_number):
# do something
Если вы просто хотите сделать что-то N раз и не нуждаетесь в итераторе.
Можно ли сделать следующее без i
?
for i in range(some_number):
# do something
Если вы просто хотите сделать что-то N раз и не нуждаетесь в итераторе.
Сверху моей головы нет.
Я думаю, что лучшее, что вы могли бы сделать, это что-то вроде этого:
def loop(f,n):
for i in xrange(n): f()
loop(lambda: <insert expression here>, 5)
Но я думаю, что вы можете просто жить с дополнительной переменной i
.
Здесь можно использовать переменную _
, которая на самом деле является просто другой переменной.
for _ in range(n):
do_something()
Обратите внимание, что _
присваивается последний результат, возвращаемый в интерактивном сеансе python:
>>> 1+2
3
>>> _
3
По этой причине я не буду использовать его таким образом. Я не знаю никакой идиомы, как упоминал Райан. Это может испортить ваш интерпретатор.
>>> for _ in xrange(10): pass
...
>>> _
9
>>> 1+2
3
>>> _
9
И согласно грамматике python, это приемлемое имя переменной:
идентификатор:: = (буква | "_" ) (буква | цифра | "_" ) *
Возможно, вы ищете
for _ in itertools.repeat(None, times): ...
это самый быстрый способ повторить итерацию times
раз в Python.
Общая идиома для назначения значения, которое не используется, - это имя _
.
for _ in range(times):
do_stuff()
Все, кто предлагает вам использовать _, не говорит, что _ часто используется как ярлык для одного из gettext функции, поэтому, если вы хотите, чтобы ваше программное обеспечение было доступно на нескольких языках, вам лучше избегать использования его для других целей.
import gettext
gettext.bindtextdomain('myapplication', '/path/to/my/language/directory')
gettext.textdomain('myapplication')
_ = gettext.gettext
# ...
print _('This is a translatable string.')
Здесь случайная идея, которая использует (злоупотребляет?) модель данных .
class Counter(object):
def __init__(self, val):
self.val = val
def __nonzero__(self):
self.val -= 1
return self.val >= 0
x = Counter(5)
while x:
# Do something
pass
Интересно, есть ли что-то подобное в стандартных библиотеках?
Вы можете использовать _11 (или любой номер или другой недопустимый идентификатор), чтобы предотвратить сопоставление имен с gettext. Каждый раз, когда вы используете символ underscore + invalid, вы получаете фиктивное имя, которое может использоваться в цикле for.
Может быть, ответ будет зависеть от того, какая у вас проблема с использованием итератора? может использоваться
i = 100
while i:
print i
i-=1
или
def loop(N, doSomething):
if not N:
return
print doSomething(N)
loop(N-1, doSomething)
loop(100, lambda a:a)
но, откровенно говоря, я не вижу смысла использовать такие подходы
t=0
for _ in range (0, 10):
print t
t = t+1
ВЫВОД:
0
1
2
3
4
5
6
7
9
Я вообще согласен с решениями, приведенными выше. А именно:
for
-loop (2 и более строк)while
(3 и более строк)__nonzero__
(еще много строк)Если нужно определить объект, как в # 3, я бы рекомендовал реализовать протокол для с ключевым словом или применить contextlib.
Далее я предлагаю еще одно решение. Это 3 лайнера и не имеет высшей элегантности, но использует пакет itertools и, следовательно, может представлять интерес.
from itertools import (chain, repeat)
times = chain(repeat(True, 2), repeat(False))
while next(times):
print 'do stuff!'
В этом примере 2 - это количество раз для итерации цикла. цепочка обертывает два итератора repeat, первый из которых ограничен, а второй бесконечен. Помните, что это истинные объекты итератора, поэтому они не требуют бесконечной памяти. Очевидно, это намного медленнее, чем решение # 1. Если не указано как часть функции, может потребоваться очистка переменной times.
Вместо ненужного счетчика теперь у вас есть ненужный список. Лучшее решение - использовать переменную, начинающуюся с "_", которая сообщает синтаксическим шашкам, что вы знаете, что вы не используете переменную.
x = range(5)
while len(x) > 0:
x.pop()
print "Work!"
Мы получили удовольствие от следующего, интересного поделиться так:
class RepeatFunction:
def __init__(self,n=1): self.n = n
def __call__(self,Func):
for i in xrange(self.n):
Func()
return Func
#----usage
k = 0
@RepeatFunction(7) #decorator for repeating function
def Job():
global k
print k
k += 1
print '---------'
Job()
Результаты:
0
1
2
3
4
5
6
---------
7
Если do_something
является простой функцией или может быть завернута в одну, простой map()
может do_something
range(some_number)
раз:
map(do_something, range(some_number))
Если вы хотите передать аргументы в do_something
, вы также можете найти itertools repeatfunc
recipe:
Чтобы передать те же аргументы:
import itertools
args = [..., my args here, ...]
itertools.starmap(do_something, itertools.repeat(args, some_number))
Чтобы передать разные аргументы:
import itertools
argses = [[1, 2], [3, 4], ...]
itertools.starmap(do_something, argses)
#Return first n items of the iterable as a list
list(itertools.islice(iterable, n))
Если вы действительно хотите избежать помещать что-то с именем (либо переменной итерации, как в OP, либо нежелательным списком, либо нежелательным генератором, возвращающим истинное требуемое количество времени), вы можете сделать это, если вы действительно хотели:
for type('', (), {}).x in range(somenumber):
dosomething()
Используется трюк для создания анонимного класса type('', (), {})
, который приводит к классу с пустым именем, но NB, что он не вставлен в локальное или глобальное пространство имен (даже если было дано непустое имя). Затем вы используете член этого класса как переменную итерации, которая недоступна, поскольку класс, членом которого он недоступен, не доступен.
В соответствии с тем, что сказал Алекс Мартелли. Неверно, что itertools.repeat()
быстрее, чем range
.
Я запускал несколько раз генерации случайных чисел в цикле for, используя оба метода итерации. В основном в повторах до 100 000 раз range
быстрее, чем itertools.repeat()
. Но когда дело доходит до повторения более 100 000 раз, оно itertools.repeat()
, которое быстрее, чем range
.
10000 times
Itertools: 0.015010
Range: 0.008006`
100000 times
Itertools: 0.091061
Range: 0.087057
1000000
Itertools: 0.846565
Range: 0.911609
Я генерировал кортежи случайных целых чисел в списке. С уважением Марек
Как насчет:
while range(some_number):
#do something