发电机理解
发电机理解是做什么的? 它是如何工作的? 我找不到关于它的教程。
你理解列表parsing吗? 如果是这样,一个生成器expression式就像是一个列表理解,而不是find你感兴趣的所有项目,并将它们打包到列表中,它将等待,并逐一从expression式中产生每个项目。
>>> my_list = [1, 3, 5, 9, 2, 6] >>> filtered_list = [item for item in my_list if item > 3] >>> print filtered_list [5, 9, 6] >>> len(filtered_list) 3 >>> # compare to generator expression ... >>> filtered_gen = (item for item in my_list if item > 3) >>> print filtered_gen # notice it's a generator object <generator object at 0xb7d5e02c> >>> len(filtered_gen) # So technically, it has no length Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: object of type 'generator' has no len() >>> # We extract each item out individually. We'll do it manually first. ... >>> filtered_gen.next() 5 >>> filtered_gen.next() 9 >>> filtered_gen.next() 6 >>> filtered_gen.next() # Should be all out of items and give an error Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration >>> # Yup, the generator is spent. No values for you! ... >>> # Let's prove it gives the same results as our list comprehension ... >>> filtered_gen = (item for item in my_list if item > 3) >>> gen_to_list = list(filtered_gen) >>> print gen_to_list [5, 9, 6] >>> filtered_list == gen_to_list True >>>
由于生成器expression式一次只能生成一个项目,因此可以大大节省内存使用量。 生成器expression式在您需要一次取一个项目的场景中最有意义,根据该项目进行大量计算,然后转到下一个项目。 如果你需要多个值,你也可以使用一个生成器expression式并且一次抓取几个值。 如果您在程序进行之前需要所有的值,请使用列表理解。
生成器理解是列表理解的懒惰版本。
它就像一个列表理解,除了它返回一个迭代器而不是列表,即一个next()方法将产生下一个元素的对象。
如果您不熟悉列表parsing,请参阅此处 ,对于生成器,请参阅此处 。
列表/发生器的理解是一个构造,你可以用它来创build一个新的列表/发生器。
假设你想要生成从1到10的每个数字的正方形列表。你可以在Python中做到这一点:
>>> [x**2 for x in range(1,11)] [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
在这里, range(1,11)
生成列表[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
,但range
函数不是Python 3.0之前的生成器,因此构造函数I已经使用的是列表理解。
如果我想创build一个同样的东西的发电机,我可以这样做:
>>> (x**2 for x in xrange(1,11)) <generator object at 0x7f0a79273488>
然而,在Python 3中, range
是一个生成器,因此结果仅取决于您使用的语法(方括号或圆括号)。
生成器理解是创build具有特定结构的生成器的简单方法。 比方说,你想要一个generator
,在your_list
所有偶数输出一个接一个。 如果你使用函数风格创build它,将会是这样的:
def allEvens( L ): for number in L: if number % 2 is 0: yield number evens = allEvens( yourList )
你可以用这个生成器理解expression式得到相同的结果:
evens = ( number for number in your_list if number % 2 == 0 )
在这两种情况下,当你调用next(evens)
你会在your_list
得到下一个偶数。
生成器理解是一种创build迭代器的方法,就像在资源上移动的光标一样。 如果你知道mysql游标或者mongodb游标,你可能会意识到整个实际的数据不会一次加载到内存中,而是一次一个。 你的光标来回移动,但内存中总是有一行/列表元素。
总之,通过使用生成器理解,你可以很容易地创buildPython中的游标。
发生器理解的另一个例子:
print 'Generator comprehensions' def sq_num(n): for num in (x**2 for x in range(n)): yield num for x in sq_num(10): print x