简体   繁体   English

itertools.cycle(iterable)vs while True

[英]itertools.cycle(iterable) vs while True

I was recently asked to do this task (school) : 我最近被要求做这个任务(学校):

Write a loop generator, which takes as parameter a finite iterable, and generates in infinite loop the iterable 编写一个循环生成器,它将参数作为有限可迭代参数,并在无限循环中生成可迭代

So I did : 所以我做了 :

import itertools
def loop(l):
    for eleme‍‌​‍‌nt in itertools.cycle(l):
        yield element

and one of my classmate did : 我的一个同学做了:

def loop(l):
    while True:
​‍         for element in l:
            yield element

I'd like to know what are the main differences between the two and if there is a more "pythonic" way to write something simple as this. 我想知道两者之间的主要区别是什么,如果有更多的“pythonic”方式来编写简单的东西。

You're right, itertools.cycle isn't of great interest here over the classical while True loop. 你是对的, itertools.cycle在经典while True循环中并不是很有趣。

On the other hand, it's of great help in infinite generator comprehensions , where you cannot create an infinite loop because it only allows for , tests and function calls. 在另一方面,这是有很大帮助的无限发电机内涵 ,在那里你不能创建一个无限循环,因为它仅允许for ,测试和函数调用。 Example to generate squared value of a list indefinitely: 无限期生成列表的平方值的示例:

generator = (x*x for x in itertools.cycle(l))

Of course you could always shorten your current code with: 当然,您可以随时缩短当前代码:

def loop(l):
    yield from itertools.cycle(l)

or even: 甚至:

loop = itertools.cycle

I'd like to know what are the main differences between the two ... 我想知道两者之间的主要区别是什么......

The main difference is that these code snippets are not entirely equivalent in behaviour. 主要区别在于这些代码片段在行为上并不完全等效。 Using cycle , you can accept and repeat an exhaustible iterator, whereas the while loop can not. 使用cycle ,您可以接受并重复一个耗尽的迭代器,而while循环则不能。

>>> def gen():
...     yield 1
...     yield 2
...     
>>> def loop_it(it):
...     for element in itertools.cycle(it):
...         yield element
...         
>>> g = loop_it(gen())
>>> next(g)
1
>>> next(g)
2
>>> next(g)
1

Contrast: 对比:

>>> def loop_while(it):
...     while True:
...         for element in it:
...             yield element
...             
>>> g = loop_while(gen())
>>> next(g)
1
>>> next(g)
2
>>> next(g)
# ... hangs forever

... and if there is a more "pythonic" way to write something simple as this ...如果有更多“pythonic”方式来编写简单的东西,就像这样

My recommendation is for the while loop, exactly as written. 我建议使用while循环,完全按照书面形式。 If you are asked in a school task to write the generator, it will likely be frowned upon to use "one prepared earlier" from itertools. 如果在学校任务中​​要求您编写生成器,则可能不赞成使用来自itertools的“之前准备的”。 The while loop is also more Pythonic. while循环也更像Pythonic。 An "itertoolsthonic" approach would instead be using the cycle directly, like this: “itertoolsthonic”方法将直接使用循环,如下所示:

items = itertools.cycle(l)
# do something with `items`

There is no point to write the extra scaffolding of a generator function and for loop yielding from an itertools.cycle - since the cycle is already an iterator, you would just use it directly. 没有必要编写一个生成器函数的额外脚手架和来自itertools.cycle的循环 - 因为循环已经是一个迭代器,你只需要直接使用它。

As I see it, the purpose of itertools.cycle is that you wouldn't have to write it yourself at all :) 正如我所看到的, itertools.cycle的目的是你不必自己编写它:)

The most pythonic way would be to simply write loop = itertools.cycle . 最pythonic的方法是简单地写loop = itertools.cycle

If you truly need to write it as a generator for your school assignment, the second form would probably perform faster, because the first form basically does the same but also has additional overhead from re-yielding the values from cycle in your generator. 如果你真的需要把它写成你的学校作业的生成器,那么第二种形式可能会更快地执行,因为第一种形式基本上是相同的,但是还有额外的开销来重新生成你的生成器中的cycle值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM