是否有可能实现一个Python范围循环没有迭代器variables?
没有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
variables一起生活。
这里是select使用_
variables,实际上,这只是另一个variables。
for _ in range(n): do_something()
请注意, _
分配了交互式python会话中返回的最后一个结果:
>>> 1+2 3 >>> _ 3
为此,我不会以这种方式使用它。 我不知道Ryan提到的任何成语。 它可能弄乱你的翻译。
>>> for _ in xrange(10): pass ... >>> _ 9 >>> 1+2 3 >>> _ 9
而根据python语法 ,这是一个可以接受的variables名称:
identifier :: =(letter |“_”)(letter | digit |“_”)*
你可能正在寻找
for _ in itertools.repeat(None, times): ...
这是在Python中迭代times
最快方法。
分配给一个没有使用的值的一般用法是把它命名为_
。
for _ in range(times): do_stuff()
大家build议你使用_并不是说频繁地将_用作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进行名称冲突。 任何时候你使用下划线+无效的标识符,你会得到一个虚拟的名字,可以在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
OUTPUT:
0 1 2 3 4 5 6 7 9
我普遍同意上面给出的解决scheme。 即:
- 在
for
-loop中使用下划线(2行以上) - 定义一个正常的计数器(3行以上)
- 用
__nonzero__
实现声明自定义类(更多行)
如果要在#3中定义一个对象,我会build议使用关键字或应用contextlib来实现协议。
另外我还提出另一个解决scheme。 这是一个3class轮,并不是至高无上的优雅,但它使用itertools包,因此可能是一个利益。
from itertools import (chain, repeat) times = chain(repeat(True, 2), repeat(False)) while next(times): print 'do stuff!'
在这些例子中, 2是迭代循环的次数。 链是包装两个重复迭代器,第一个是有限的,但第二个是无限的。 请记住,这些是真正的迭代器对象,因此它们不需要无限的内存。 显然这比解决scheme#1慢得多。 除非作为函数的一部分写入,否则可能需要清理次数variables。
而不是一个不需要的柜台,现在你有一个不需要的名单。 最好的解决scheme是使用一个以“_”开头的variables,告诉语法检查者你知道你没有使用variables。
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中的迭代variables,或者不需要的列表或不需要的生成器返回真正所需的时间量),你可以这样做,如果你真的想要:
for type('', (), {}).x in range(somenumber): dosomething()
使用的技巧是创build一个匿名类type('', (), {})
,它将产生一个空名称的类,但是注意它并没有被插入本地或全局名称空间中(即使非空名称是提供)。 然后你使用这个类的成员作为迭代variables,这是不可达的,因为它所属的类是不可达的。
根据什么亚历克斯Martelli说。 itertools.repeat()
比range
更快是不正确的。
我使用两种迭代方法在for循环中运行了几代随机数。 基本上重复最多100 000次的range
比itertools.repeat()
更快。 但是当重复超过10万次时, 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