是否可以在没有迭代器变量的情况下为范围循环实现Python?

Jam*_*hon 176 python loops for-loop range

没有这个可以做以下i吗?

for i in range(some_number):
    # do something
Run Code Online (Sandbox Code Playgroud)

如果你只是想做N次,并且不需要迭代器.

Unk*_*own 97

在我的头顶,没有.

我认为你能做的最好的是这样的:

def loop(f,n):
    for i in xrange(n): f()

loop(lambda: <insert expression here>, 5)
Run Code Online (Sandbox Code Playgroud)

但我认为你可以忍受额外的i变量.

这是使用_变量的选项,实际上,它只是另一个变量.

for _ in range(n):
    do_something()
Run Code Online (Sandbox Code Playgroud)

请注意,_分配了交互式python会话中返回的最后一个结果:

>>> 1+2
3
>>> _
3
Run Code Online (Sandbox Code Playgroud)

出于这个原因,我不会以这种方式使用它.我不知道Ryan提到的任何成语.它会弄乱你的口译员.

>>> for _ in xrange(10): pass
...
>>> _
9
>>> 1+2
3
>>> _
9
Run Code Online (Sandbox Code Playgroud)

根据Python语法,它是一个可接受的变量名称:

identifier ::= (letter|"_") (letter | digit | "_")*
Run Code Online (Sandbox Code Playgroud)

  • "但我认为你可以忍受额外的"我""是的,这只是一个学术观点. (3认同)
  • @kurczak有一点。使用`_`可以清楚地将其忽略。说这样做是没有意义的,就像说注释代码没有意义-因为它仍然会完全一样。 (3认同)
  • 这是一个变量. (2认同)
  • 使用“_”而不是“i”的另一个很好的理由是,pylint(可能还有其他 linter)会将“_”读取为丢弃,并且不会给出未使用的变量警告。 (2认同)

Ale*_*lli 69

你可能正在寻找

for _ in itertools.repeat(None, times): ...
Run Code Online (Sandbox Code Playgroud)

这是times在Python中迭代次数的最快方法.

  • 这很有意思,我没有意识到这一点.我刚看了一下itertools文档; 但我想知道为什么这比使用范围或xrange更快? (5认同)
  • @blackkettle:它更快,因为它不需要返回当前的迭代索引,这是xrange(和Python 3的范围,它给出迭代器而不是列表)成本的可测量部分.@ nemo,range尽可能优化,但是需要构建和返回一个列表不可避免地比迭代器更重要(在Py3中,range确实返回迭代器,就像Py2的xrange;向后兼容性不允许这样的改变在Py2)中,尤其是不需要返回变化值的那个. (5认同)
  • @Cristian,是的,每次都准备并返回一个Python int,inc.gc工作,确实有可衡量的成本 - 使用计数器_internally_无所谓. (4认同)
  • 我现在知道了.差异来自GC开销,而不是来自"算法".顺便说一句,我运行一个快速*timeit*基准测试,加速是~1.42倍. (4认同)
  • 我并不关心性能,我只是很好奇是否有更简洁的方式来编写声明.虽然我已经偶尔使用Python大约2年了,但我仍然觉得有很多我不知道.Itertools就是其中之一,感谢您提供的信息. (2认同)

Rya*_*yan 56

分配给未使用的值的一般习惯用法是命名它_.

for _ in range(times):
    do_stuff()
Run Code Online (Sandbox Code Playgroud)


Ign*_*ams 18

每个人建议你使用_并不是说_经常被用作其中一个gettext函数的快捷方式,所以如果你想让你的软件以多种语言提供,那么你最好避免使用它用于其他目的.

import gettext
gettext.bindtextdomain('myapplication', '/path/to/my/language/directory')
gettext.textdomain('myapplication')
_ = gettext.gettext
# ...
print _('This is a translatable string.')
Run Code Online (Sandbox Code Playgroud)

  • 对我来说,使用 `_` 似乎是一个糟糕的主意,我不介意与它发生冲突。 (2认同)

saf*_*fsd 9

这是一个利用(滥用?)数据模型(Py3链接)的随机想法.

class Counter(object):
    def __init__(self, val):
        self.val = val

    def __nonzero__(self):
        self.val -= 1
        return self.val >= 0
    __bool__ = __nonzero__  # Alias to Py3 name to make code work unchanged on Py2 and Py3

x = Counter(5)
while x:
    # Do something
    pass
Run Code Online (Sandbox Code Playgroud)

我想知道标准库中是否有这样的东西?

  • 我认为有一个带有副作用的方法如`__nonzero__`是一个可怕的想法. (9认同)
  • 我会改用`__call__`。`while x():` 并没有那么难写。 (2认同)
  • 还有一个论点是避免使用“Counter”这个名字;当然,它不是保留的或在内置范围内,但是 [`collections.Counter` 是一个东西](https://docs.python.org/3/library/collections.html#collections.Counter),并且使同名的类可能会导致维护者混淆(并不是说这已经没有风险了)。 (2认同)

Jir*_*kaV 7

您可以使用_11(或任何数字或其他无效标识符)来防止使用gettext进行名称整理.每次使用下划线+无效标识符时,都会得到一个可用于for循环的虚拟名称.