[英]When to drop list Comprehension and the Pythonic way?
我創建了一個以下列方式將對象附加到列表的行
>>> foo = list()
>>> def sum(a, b):
... c = a+b; return c
...
>>> bar_list = [9,8,7,6,5,4,3,2,1,0]
>>> [foo.append(sum(i,x)) for i, x in enumerate(bar_list)]
[None, None, None, None, None, None, None, None, None, None]
>>> foo
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
>>>
這條線
[foo.append(sum(i,x)) for i, x in enumerate(bar_list)]
會給一個pylint W1060表達式什么都沒有,但由於我已經在使用foo列表來附加值,所以我不需要將List Comprehension行賦予某些東西。
我的問題更多的是編程正確性
我應該刪除列表理解並使用簡單的表達式嗎?
>>> for i, x in enumerate(bar_list):
... foo.append(sum(i,x))
或者是否有正確的方法來使用列表理解和分配到什么?
回答
謝謝@ user2387370,@ kindall和@Martijn Pieters。 對於其余的注釋,我使用append,因為我沒有使用list(),我沒有使用i + x,因為這只是一個簡化的例子。
我把它留下如下:
histogramsCtr = hist_impl.HistogramsContainer()
for index, tupl in enumerate(local_ranges_per_histogram_list):
histogramsCtr.append(doSubHistogramData(index, tupl))
return histogramsCtr
是的,這是不好的風格。 列表理解是建立一個列表。 您正在構建一個完整的清單None
秒,然后把它扔了。 您實際需要的結果是這項工作的副作用。
為什么不首先使用列表理解來定義foo
?
foo = [sum(i,x) for i, x in enumerate(bar_list)]
如果它不是一個列表而是一些其他容器類,正如你在另一個答案的注釋中提到的那樣,寫一個類來接受它的構造函數中的一個iterable(或者,如果它不是你的代碼,則將它子類化為這樣做),然后傳遞一個生成器表達式:
foo = MyContainer(sum(i, x) for i, x in enumerate(bar_list))
如果foo
已經有一些價值並且您希望追加新項目:
foo.extend(sum(i,x) for i, x in enumerate(bar_list))
如果你真的想使用append()
並且由於某些原因不想使用for
循環,那么你可以使用這個結構; 生成器表達式至少可以避免在您不想要的列表上浪費內存和CPU周期:
any(foo.append(sum(i, x)) for i, x in enumerate(bar_list))
但是這比常規for
循環更不清楚,還有一些額外的工作要做: any
都在每次迭代時測試foo.append()
的返回值。 您可以編寫一個函數來使用迭代器並消除該檢查; 最快的方法是使用零長度collections.deque
:
from collections import deque
do = deque([], maxlen=0).extend
do(foo.append(sum(i, x)) for i, x in enumerate(bar_list))
這實際上是相當可讀的,但我相信它實際上並不比any()
更快,並且需要額外的導入。 但是, do()
或any()
比for
循環快一點,如果這是一個問題。
我認為通常不贊成使用列表推導僅用於副作用,所以我想說for循環在這種情況下更好。
但無論如何,你不能只做foo = [sum(i,x) for i, x in enumerate(bar_list)]
?
你絕對應該放棄列表理解。 結束。
在您的簡化案例中,您忽略了您可以直接使用列表推導的事實:
[sum(i,x) for i, x in enumerate(bar_list)]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.