【问题标题】:Loop for `times` if `times is not None` else loop forever如果 `times 不是 None` 则循环 `times` 否则永远循环
【发布时间】:2017-11-22 00:24:02
【问题描述】:

假设我有一个表单的函数

def foo(times=None):
    iterator = range(times) if times else itertools.count()
    for _ in iterator:
        # do stuff

是否有更 Pythonic 或更优雅的方式来完成此任务?

【问题讨论】:

  • 可能是显而易见的,但如果您可能会永远循环,那么您确实在您的“做事”中有一个break 条件?
  • @idjaw 是的,这是用于在放弃之前尝试函数times 次的装饰器(如果引发异常)。如果时间是None,则装饰器会继续尝试该功能,直到KeyboardInterrupt
  • 这对我来说似乎很好。就个人而言,除了键盘中断之外,我可能还有其他东西可以“帮助”摆脱那个无限循环。但是,对我来说这看起来不错。
  • @idjaw 这有点浪费,因为count 无缘无故地执行所有这些添加。通常我也讨厌为了这样一个简单的目的而不得不做一个完整的三元和变量赋值。
  • 发布的最新答案做了一些有趣的事情。我忘了重复。很有趣。

标签: python python-3.x loops iterator iteration


【解决方案1】:

首先,如果您不使用变量,就像您使用_ 作为名称一样,请使用itertools.repeat(None),因为它更接近您想要做的事情,而且非常效率略高。

如果您已经在使用itertools.repeat,请使用第二个times 参数:

def foo(*times):
    for _ in itertools.repeat(None, *times):
        # do stuff

如果你不想破坏签名,你可以这样做:

def foo(times=None):
    for _ in itertools.repeat(*((None, times) if times is not None else (None,))):
        # do stuff

这看起来不太优雅,但可以防止您意外提供过多的参数。

【讨论】:

  • 这正是我想要的!一种在自然迭代器中组合这两种情况的方法。它还摆脱了count 中的无用添加。谢谢!
  • @RenéG 请注意,无用的添加是非常少的 CPU 时间,太少而无法真正关心。
  • 等等,你为什么用*times而不是times
  • @RenéG 由于itertools.repeat 的实现方式,itertools.repeat(None, None) 会引发错误。使用 *times 意味着如果它不存在,它不提供 arg。
  • 为什么不引发NoneType is not iterable?文档没有说明第一个参数是 None
猜你喜欢
  • 2011-02-09
  • 1970-01-01
  • 2014-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多