簡體   English   中英

如何識別生成器與列表理解

[英]How to identify a generator vs list comprehension

我有這個:

>>> sum( i*i for i in xrange(5))

我的問題是,在這種情況下, 我是否將列表理解或生成器對象傳遞給總和? 我怎么說呢? 圍繞這個有一般規則嗎?

另外,請記住sum本身需要一對括號來包圍它的參數。 我認為上面的括號是求和而不是創建生成器對象。 你不同意嗎?

你正在傳遞一個生成器表達式

列表推導用方括號[...] )指定。 列表推導首先構建列表對象 ,因此它使用與列表文字語法密切相關的語法:

list_literal = [1, 2, 3]
list_comprehension = [i for i in range(4) if i > 0]

另一方面,生成器表達式創建一個迭代器對象。 該對象迭代時執行包含環和是生產的物品。 生成器表達式不保留這些項; 沒有列表對象正在構建。

生成器表達式總是使用(...)圓形parethesis,但當用作調用的唯一參數時,可以省略括號; 以下兩個表達式是等效的:

sum((i*i for i in xrange(5)))  # with parenthesis
sum(i*i for i in xrange(5))    # without parenthesis around the generator

引用生成器表達式文檔:

對於只有一個參數的調用,可以省略括號。 請參閱呼叫詳細信息部分。

列表推導包含在[]

>>> [i*i for i in xrange(5)]  # list comprehension
[0, 1, 4, 9, 16]
>>> (i*i for i in xrange(5))  # generator
<generator object <genexpr> at 0x2cee40>

你正在通過一台發電機。

那是一個發電機:

>>> (i*i for i in xrange(5))
<generator object <genexpr> at 0x01A27A08>
>>>

列表推導包含在[]

您可能也會問,“這種語法真的會導致sum消耗一個生成器項目,還是先秘密創建生成器中每個項目的list ”? 檢查此問題的一種方法是在非常大的范圍內嘗試並觀察內存使用情況:

sum(i for i in xrange(int(1e8)))

這種情況下的內存使用是不變的,其中range(int(1e8))創建完整列表並消耗數百MB的RAM。

您可以測試括號是否可選:

def print_it(obj):
    print obj

print_it(i for i in xrange(5))
# prints <generator object <genexpr> at 0x03853C60>

我試過這個:

#!/usr/bin/env python

    class myclass:

            def __init__(self,arg):
                    self.p = arg
                    print type(self.p)
                    print self.p





    if __name__ == '__main__':

            c = myclass(i*i for i in xrange(5))

這打印:

$ ./genexprorlistcomp.py 
<type 'generator'>
<generator object <genexpr> at 0x7f5344c7cf00>

這與Martin和mdscruggs在帖子中解釋的內容一致。

你正在傳遞一個生成器對象,列表理解被[]包圍。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM