total = sum([float(item) for item in s.split(",")])
total = sum(float(item) for item in s.split(","))
來源:https://stackoverflow.com/a/21212727/1825083爲什麼以下兩行代碼有區別?
total = sum([float(item) for item in s.split(",")])
total = sum(float(item) for item in s.split(","))
來源:https://stackoverflow.com/a/21212727/1825083爲什麼以下兩行代碼有區別?
第一個使用一個list comprehension編譯所有浮點值的列表。
第二個使用generator expression建立一個發電機只作爲請求建立的每個浮點值,一個的時間。當列表非常大時,這會節省大量內存。
生成器表達式也可能更快(因爲它允許工作流水線化並避免內存分配時間)或更慢(因爲它增加了一點開銷),但通常不是在它們之間進行選擇的好理由。只要按照這個經驗簡單的規則:
如果你需要一個列表(或者,更可能的是,只是你可以存儲,循環過多次,打印等),建立一個列表。如果你只需要遍歷這些值,不要建立一個列表。
在這種情況下,顯然,您不需要列表,因此請將方括號關閉。
在Python 2.x中,還有一些其他的細微差別;在3.x中,列表理解實際上被定義爲只是在生成器表達式上調用list
函數。 (雖然至少在3.0-3.3小錯誤,這錯誤,如果你去尋找它很辛苦,你只能找到...)
現在好奇這個bug。 :P –
@SukritKalra:我會給你一個提示:嘗試從理解的各個地方調用調用「提升StopIteration」和「提升GeneratorExit」的函數。 – abarnert
@SukritKalra:如果你放棄,請參閱[本博文](http://stupidpythonideas.blogspot。COM/2013/06 /罐您-優化-listgenexp.html)。我不是100%確定我給出的例子是唯一的區別。我很確定最後提出的補丁不僅消除了這種差異,還消除了其他未被發現的差異。 (順便說一句,我的目標是試驗一個窺視孔優化器,用於直接從genexprs中創建序列的代碼,並且我受到了一些限制。) – abarnert
第一個創建一個列表,以及資金在列表中的號碼。這是一筆
第二個計算每個項目反過來,並將其添加到正在運行的總內部列表解析,並返回運行總的總和,當所有的項目都用盡。這是一個生成器理解。
它根本不創建列表,這意味着它不需要額外的時間爲列表分配內存並填充它。這也意味着,它具有更好的空間複雜度,因爲它僅使用常數空間(調用float
;從調用split
,這兩個行做除外)
第一個使一個列表,而第二個是一個生成器表達式。在沒有sum()
函數調用的情況下嘗試使用它們。
In [25]: [float(a) for a in s.split(',')]
Out[25]: [1.23, 2.4, 3.123]
In [26]: (float(a) for a in s.split(','))
Out[26]: <generator object <genexpr> at 0x0698EF08>
In [27]: m = (float(a) for a in s.split(','))
In [28]: next(m)
Out[28]: 1.23
In [29]: next(m)
Out[29]: 2.4
In [30]: next(m)
Out[30]: 3.123
所以,第一個表達式首先在內存中創建整個列表,然後計算總和,而第二個剛剛得到在表達的下一個項目,並將其添加到其目前的總。 (更多存儲器高效)
正如其他人所說,第一創建的列表,而第二創建生成的所有值的發電機。你可能會關心這個問題的原因是創建列表會將所有元素一次存儲到內存中,而使用生成器時,可以在生成時處理它們,而不必將它們全部存儲起來,這對於大量數據可能很重要。
我不知道這是否是值得一提的答案'str.join'和少數其他函數將接受迭代器,但立即調用'list()'。所以我只是在評論中提到它。 – abarnert