Python 有无限迭代器的表达式吗?
是否有一个可以产生无限迭代器的直接表达式 这是一个纯粹的理论问题。这里不需要“实际”的答案:)Python 有无限迭代器的表达式吗?,python,iterator,generator,infinite-loop,Python,Iterator,Generator,Infinite Loop,是否有一个可以产生无限迭代器的直接表达式 这是一个纯粹的理论问题。这里不需要“实际”的答案:) 例如,很容易使用生成器表达式生成有限迭代器: my_gen = (0 for i in xrange(42)) 但是,要创建一个无限的名称空间,我需要使用一个伪函数“污染”我的名称空间: def _my_gen(): while True: yield 0 my_gen = _my_gen() 在单独的文件中执行操作和以后导入都不算数 我也知道,itertools.re
例如,很容易使用生成器表达式生成有限迭代器:
my_gen = (0 for i in xrange(42))
但是,要创建一个无限的名称空间,我需要使用一个伪函数“污染”我的名称空间:
def _my_gen():
while True:
yield 0
my_gen = _my_gen()
在单独的文件中执行操作和以后导入都不算数
我也知道,
itertools.repeat
就是这样做的。我很好奇是否有一个没有它的单线性解决方案。没有一个在内部不使用另一个定义为类/函数/生成器的无限迭代器(非表达式,一个具有产量的函数)。生成器表达式总是从另一个iterable中提取,除了过滤和映射它的项之外什么也不做。只有map
和filter
,你不能从有限项变成无限项,你需要while
(或者一个不终止的for
,这正是我们仅使用for
和有限迭代器所不能得到的)
琐事:表面上很相似,但仔细检查后,它似乎仍然需要for
子句(因此没有(0为True)
),即只为itertools提供了一个快捷方式。takewhile
也许您可以使用这样的装饰程序,例如:
def generator(first):
def wrap(func):
def seq():
x = first
while True:
yield x
x = func(x)
return seq
return wrap
用法(1):
用法(2)
我认为它可以进一步改进,以摆脱那些丑陋的()
。但是,这取决于您希望能够创建的序列的复杂性。一般来说,如果序列可以使用函数表示,那么生成器的所有复杂性和语法优势都可以隐藏在装饰器或类似装饰器的函数中。提供了三个无限迭代器:
- :0,1,2,3,4
- :p[0],p[1],…,p[-1],p[0]
- :x,x,x,x
我不知道标准图书馆里还有其他人
既然你要的是一艘班轮:
__import__("itertools").count()
你的操作系统可能会提供一些可以用作无限生成器的东西。例如在linux上
for i in (0 for x in open('/dev/urandom')):
print i
显然,这并不像以前那样有效
for i in __import__('itertools').repeat(0)
print i
- 双参数
iter
=零参数可调用+哨兵值
int()
始终返回0
因此,iter(int,1)
是一个无限迭代器。显然,在这个特定的主题上有大量的变体(特别是当您将lambda
添加到混合中时)。特别值得注意的一个变体是iter(f,object())
,因为使用新创建的对象作为sentinel值几乎保证了一个无限迭代器,而不管第一个参数使用的是哪个可调用对象。您可以对可调用对象进行迭代,返回的常量始终不同于iter()的sentinel
g1=iter(lambda:0, 1)
非常丑陋和疯狂(但是非常有趣),但是您可以使用一些技巧从表达式中构建自己的迭代器(而不会根据需要“污染”名称空间):
OP要求一个单行线,您提供了一个10行的装饰器,其中包含三个嵌套的def
和闭包?;)@delnan很好,但是如果你定义一次装饰师,你就可以有一行了,不是吗?据我所知,目的是在一行中实现每个额外的无限生成器。这就是这里介绍的内容。你可以有(2^x)
,你可以有(x)
。如果你稍微改进一下,可能斐波那契等也不能回答我的问题,但是你怎么能不喜欢那些毛茸茸的闭包呢?顺便说一句,我很确定你可以通过去掉seq
并将代码直接缩进wrap
来去掉多余的参数,实际上你不需要污染你的名称空间。。。只需将函数命名为my\u gen
,然后执行my\u gen=my\u gen()
。如果您不想像我怀疑的那样混淆两者,也可以使用del\u my\u gen
。。。那么我们能确定没有现成的无限发电机可以滥用吗?(遗憾的是,xrange(0,1,-1)不起作用…@missingno:从itertools导入repeat,count,cycle
可能被大多数人视为“随时可用”。哎呀,我忘记了2参数iter
。无限迭代器实际上是内置的-请参见我的答案:)/dev/uradom解决方案取决于不时出现的\n
s。。。狡猾的!:)使用iter
和int
属性的非常有趣的方法,我们已经多次忘记了它。您可以使用这个神奇的方法来模拟itertools.count
:count=lambda start=0,step=1:(start+i*step for i,uu)在枚举(iter(int,1))中)
只是解释一下这里发生了什么:当使用两个参数调用iter
-函数时,它的行为与正常情况略有不同:iter(可调用,sentinel)->迭代器
。参数1,callable
将为迭代器的每次迭代调用,直到它返回sentinel
的值。但是,由于int()
将始终返回0
,因此我们可以永远调用int()
,永远不会到达1。这实际上会产生一个无限的0
重复(x,次)列表=∞) - 没有∞代码>任何想知道的人的符号-省略参数会使重复运行EverUppoted,因为(虽然ncoghlan的答案直接解决了OP的问题)这更普遍适用。这比iter(int,1)
咒语可读性好得多。太糟糕了itertools
没有一个无限()
方法,其唯一目的就是这样做;itertools.count()
也不是那么可读。我既喜欢也讨厌这个…我喜欢它用这么少的字符就完成了我想要的,但讨厌没有人会看到它,知道它是什么
for i in __import__('itertools').repeat(0)
print i
for x in iter(int, 1): pass
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,), {}))() }