我想知道是否可能执行一定数量的操作而不在任何地方存储循环迭代数。
例如,假设我想要在控制台上打印两个“hello”消息。目前我知道可以这样做:
for i in range(2):
print "hello"
但是,i
变量将会取值为0
和1
(我实际上并不需要这些值)。有没有一种方法可以在不存储这些不需要的值的情况下实现同样的功能?
不用说,使用变量根本不是什么大问题......我只是好奇。
在编程中,一个未使用的变量惯用语(被很多其他语言共享)是一个下划线 _
。代码分析器通常不会抱怨 _
没有使用,并且程序员立即知道它是 i_dont_care_wtf_you_put_here
的快捷方式。没有办法进行迭代而没有项目变量 - 正如 Python 之禅所说,“特殊情况并不足以打破规则”。
exec 'print "hello";' * 2
应该可以工作,但我有点感到羞愧,因为我想到了这个方法。
更新:我又想到了另一个方法:
for _ in " "*10: print "hello"
我认为你在问题中提供的for循环已经是最好的了,但我想指出未使用的变量可以分配给名为_
的变量,这是一种“丢弃”所分配值的约定。尽管_
引用将保存您赋予它的值,但代码 linters 和其他开发人员将了解您未使用该引用。因此这是一个例子:
for _ in range(2):
print('Hello')
其他人已经讨论了在for
循环中无法完全避免迭代变量的问题,但有一些选项可以减少一点点工作量。毕竟,range
必须生成大量数字,这涉及一点点工作;如果你想避免甚至这一点点工作,你可以使用itertools.repeat
只是不断地获得相同(被忽略的)值,这不涉及创建/检索不同的对象:
from itertools import repeat
for _ in repeat(None, 200): # Runs the loop 200 times
...
for _ in range(200):
运行得更快,但如果循环体执行有意义的工作,则这只是杯水车薪。而且,与将某些匿名序列乘以您的循环可迭代对象不同,repeat
仅具有微不足道的设置成本,并且没有与长度相关的内存开销。虽然我完全同意delnan的回答,但这并非不可能:
loop = range(NUM_ITERATIONS+1)
while loop.pop():
do_stuff()
False
,您将得到另一个迭代,并在下一次通过时引发异常:IndexError: pop from empty list
。此外,在循环之后,你的列表(loop
)将会变为空。仅供好奇参考。;)loop = reversed(range(NUM_ITERATIONS + 1))
进行初始化,然后使循环打开while next(loop):
。通过使用范围对象上的反向迭代器(按需生成它们而不是急切地提前生成它们),将产生相同顺序的相同值。 - ShadowRangerxrange
,但它略微丑陋(xrange
不支持反向迭代,因此您必须手动提供所有三个参数,并以相反的顺序操作,这看起来有点丑陋以设置结束点):初始化将是 loop = iter(xrange(NUM_ITERATIONS, -1, -1))
,而 while
与 Py3 中相同(至少在 2.6+ 上;在 2.6 之前,您需要执行 while loop.next():
,但希望即使在 2.7 结束支持两年后,也没有人仍在使用 2.5 或更早版本)。 - ShadowRangeri
…[print('hello') for i in range(3)]
i
在列表推导式之外将不存在,这与for循环不同。 - Sam Hartmani
将存在于列表推导之外,但在Py3中不存在。在Py2中,列表推导没有单独的作用域,但在Py3中(以及对于Py2上的genexprs和setcomp/dictcomps),它们在闭包作用域中运行,其中迭代变量是局部于闭包作用域的,不能在其外部看到。列表推导与所有其他推导/genexprs之间的差异是Py2和Py3之间简化(以兼容性破坏方式)的事情之一。 - ShadowRanger抱歉,为了在任何语言中进行迭代,包括Python和英语,都必须存储索引。无论是否在变量中。找到一种方式来隐藏Python内部跟踪for循环的事实并不会改变它的事实。我建议您将其保留原样。
print 2*'hello'
for word in ['hello'] * 2:
print word
虽然这不是 Python 的习惯用法,但你试图做的也不是。
def g(): { while True: { if random.random() < 0.1: { break } else { yield 1 } } } }
。g()
是一个生成器; 在任何给定时间,迭代停止的机会为1/10,且没有任何迭代变量(严格来说random.random()
具有内部状态,您可以认为它是迭代变量的替代,但我们可以根据外部源(例如http://www.random.org/)实现`random.random()`,在这种情况下,没有东西可以预测迭代何时停止)。 - jfs
Loop, 5 { ...}
这样的东西(简单地重复一个动作5次)在其他地方不存在。不需要使用变量,同时提高可读性。 - phil294gettext
i18n和其解释器预定义变量中。i
看起来更好。 - ubombi