有无限迭代器的表达式吗?

是否有一个直接的表达式可以产生一个无限的迭代器?

这纯粹是一个理论问题,不需要“实际”的回答:)


例如,很容易使用生成器表达式来创建有限迭代器:

my_gen = (0 for i in xrange(42))

然而,要创建一个无限的名称空间,我需要用一个伪函数“污染”我的名称空间:

def _my_gen():
while True:
yield 0
my_gen = _my_gen()

在一个单独的文件中执行操作并且以后进行 import不算数。


我也知道 itertools.repeat正是这样做的。我很好奇是否有一个一行程序的解决方案没有这一点。

83071 次浏览

没有一个不在内部使用另一个定义为类/函数/生成器(not-expression,具有 yield的函数)的无限迭代器。生成器表达式总是从另一个迭代器中提取,除了筛选和映射其项目之外什么也不做。你不能只用 mapfilter从有限的项目到无限的项目,你需要 while(或者一个不终止的 for,这正是我们不能只使用 for和有限的迭代器)。

花絮: PEP 3142表面上看起来很相似,但是仔细一看,它似乎仍然需要 for子句(所以你没有 (0 while True)) ,也就是说,它只提供了 itertools.takewhile的一个快捷方式。

也许你可以使用这样的装潢师,例如:

def generator(first):
def wrap(func):
def seq():
x = first
while True:
yield x
x = func(x)
return seq
return wrap

用法(一) :

@generator(0)
def blah(x):
return x + 1


for i in blah():
print i

用法(2)

for i in generator(0)(lambda x: x + 1)():
print i

我认为它可以进一步改进,以摆脱那些丑陋的 ()。然而,这取决于您希望能够创建的序列的复杂性。一般来说,如果序列可以用函数表示,那么生成器的所有复杂性和语法糖就可以隐藏在修饰符或类似修饰符的函数中。

itertools 提供了三个无限迭代器:

我不知道标准图书馆还有其他的。


既然你说了一句俏皮话:

__import__("itertools").count()

你的操作系统可以提供一些可以用作无限生成器的东西

for i in (0 for x in open('/dev/urandom')):
print i

显然这不如

for i in __import__('itertools').repeat(0)
print i
for x in iter(int, 1): pass
  • 双参数 iter = 零参数可调用 + 前哨值
  • int()始终返回 0

因此,iter(int, 1)是一个无限迭代器。显然,在这个特定的主题上有大量的变体(特别是当您将 lambda添加到组合中时)。特别值得注意的一个变体是 iter(f, object()),因为使用新创建的对象作为前哨值几乎保证了无限迭代器,而不管第一个参数使用的是哪个可调用参数。

您可以迭代一个可调用函数,返回一个总是不同于 iter ()的前哨的常量

g1=iter(lambda:0, 1)

非常丑陋和疯狂(但是非常有趣) ,但是你可以通过使用一些技巧从一个表达式构建你自己的迭代器(不会“污染”你的名称空间) :

{ 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,), {}))() }