是否存在无限生成器的表达式?

hug*_*omg 104 python iterator generator infinite-loop

是否存在可以产生无限元素的直接生成器表达式?

这是一个纯粹的理论问题.这里不需要"实用"的答案:)


例如,很容易制作一个有限的发电机:

my_gen = (0 for i in xrange(42))
Run Code Online (Sandbox Code Playgroud)

但是,要创建一个无限的,我需要使用伪造的函数"污染"我的命名空间:

def _my_gen():
    while True:
        yield 0
my_gen = _my_gen()
Run Code Online (Sandbox Code Playgroud)

在单独的文件中执行操作并在import以后执行操作不计算在内.


我也知道这就是itertools.repeat这个.我很好奇是否有一个没有它的单线解决方案.

Kat*_*iel 184

itertools 提供三个无限生成器:

我不知道标准库中的任何其他人.


既然你要求一个单行:

__import__("itertools").count()
Run Code Online (Sandbox Code Playgroud)

  • Re:重复(x,times =∞) - 对于想知道的人没有"∞"符号 - 省略参数使重复运行永远 (16认同)
  • 这比 `iter(int, 1)` 咒语更具可读性。太糟糕了`itertools` 没有一个`endless()` 方法,它的唯一目的就是这样做;`itertools.count()` 也不是那么易读。 (4认同)

nco*_*lan 123

for x in iter(int, 1): pass
Run Code Online (Sandbox Code Playgroud)
  • 双参数iter=零参数可调用+哨兵值
  • int() 总是回来 0

因此,iter(int, 1)是一个无限的迭代器.这个特定的主题显然有很多变化(特别是一旦你添加lambda到混合中).特别注意的一个变体是iter(f, object()),使用新创建的对象作为sentinel值几乎保证无限迭代器,而不管用作第一个参数的可调用对象.

  • 只是为了解释这里发生的事情:当使用两个参数调用“iter”函数时,它的行为与正常情况略有不同:“iter(callable, sentinel) -> iterator”。参数 1,迭代器的每次迭代都会调用“callable”,*直到*它返回“sentinel”的值。然而,由于 `int()` 总是返回 `0`,所以我们可以永远调用 `int()` 并且永远不会达到 1。这实际上会产生一个无限的 `0` 列表 (9认同)
  • 非常有趣的方式使用`iter`与`int`的属性,我们很多次忘记了. (3认同)
  • 你可以使用这个神奇的配方来模拟`itertools.count`:`count = lambda start = 0,step = 1 :(开始+ i*步骤为i,_为枚举(iter(int,1))) (2认同)

use*_*419 16

你可以遍历一个可调用的函数,返回一个总是与iter()的哨兵不同的常量

g1=iter(lambda:0,1)
Run Code Online (Sandbox Code Playgroud)

  • 我既爱又恨这个...我喜欢它以如此少的角色完成我想要的东西,但又讨厌没有人会去看它并知道它应该做什么. (6认同)
  • 知道 `iter` 的语法(这里有额外的哨兵)和 `lambda` 的语法(这里没有任何传递的参数,只有 `return 0`),唯一讨厌的地方就是那个神秘的 `g1`。 (2认同)

Joh*_*ooy 6

您的操作系统可能会提供可用作无限生成器的内容.例如在linux上

for i in (0 for x in open('/dev/urandom')):
    print i
Run Code Online (Sandbox Code Playgroud)

显然这不如效率高

for i in __import__('itertools').repeat(0)
    print i
Run Code Online (Sandbox Code Playgroud)

  • / dev/urandom解决方案取决于`\n'不时出现......狡猾!:) (11认同)

Tho*_*hel 6

非常丑陋和疯狂(然而非常有趣),但是您可以使用一些技巧从表达式构建自己的迭代器(无需“污染”您的命名空间):

{ print("Hello world") for _ in
    (lambda o: setattr(o, '__iter__', lambda x:x)
            or setattr(o, '__next__', lambda x:True)
            or o)
    (type("EvilIterator", (object,), {}))() } 
Run Code Online (Sandbox Code Playgroud)


小智 5

没有在内部不使用另一个定义为类/函数/生成器的无限迭代器(不是--expression,函数yield).生成器表达式始终从anoter iterable中抽取,除了过滤和映射其项之外什么也不做.您无法从有限的项目去只有那些无限mapfilter,你需要while(或for不终止,这正是我们不能只使用for和有限的迭代器).

琐事:PEP 3142在表面上是相似的,但经过仔细检查,它似乎仍然需要for条款(所以不(0 while True)适合你),即只提供一个快捷方式itertools.takewhile.

  • @missingno:`来自itertools import repeat,count,cycle`可能被大多数人视为"随时可用". (2认同)