2013-07-30 27 views
3

我創建了一個附加的對象列表下面的方式行何時下降列表理解和Pythonic的方式?

>>> 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列表來追加我不需要賦予列表理解行的值。

我的問題是更多的程序正確性的問題

我應該放棄列表理解,只需使用一個簡單的表達?

>>> for i, x in enumerate(bar_list): 
...  foo.append(sum(i,x)) 

還是有沒有正確的方法來使用列表理解和分配任何東西?

回答

謝謝@ user2387370,@kindall和@Martijn皮特斯。對於其餘的評論我使用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 
+0

我意識到這只是一個例子,但爲什麼要附加?爲什麼不只是'foo = [sum(i,x)...]'? –

+0

'sum(i,x)'不起作用。你的意思是'i + x'? – user2357112

+0

如果你真的想要一個班輪,你可以把一個'for'循環放在一行上。不過不推薦。 – user2357112

回答

8

是的,這是不好的風格。列表理解是建立一個列表。你正在建立一個充滿None的清單,然後把它扔掉。你的實際期望結果是這種努力的副作用。

爲什麼不首先使用列表理解來定義foo

foo = [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循環稍快。

7

我認爲這是通常在使用只是副作用列表內涵皺起了眉頭,所以我會說一個for循環在這種情況下更好。

但無論如何,難道你只是做foo = [sum(i,x) for i, x in enumerate(bar_list)]

+0

因爲在我的程序中,foo是一個容器對象,所以append方法會執行一些其他操作。 – Claudiordgz

+1

然後,不要在你的問題中顯示它爲'list'! – kindall

+1

然後或者只是使用一個for循環,或者如果容器對象是你定義的類的一個類,也許可以改變'__init__'來使用* args,這樣你就可以爲'foo = MyContainerFoo(sum(i,x)枚舉中的x(bar_list))' – rlms

3

你應該絕對是放下列表修真。結束。

  • 你在混淆閱讀你的代碼的人。你正在建立一個副作用列表。
  • 您正在支付CPU週期和內存,用於構建要再次丟棄的列表。

在您的簡化的情況,您可俯瞰事實上,你可能已經直接使用列表理解:

[sum(i,x) for i, x in enumerate(bar_list)]