2010-01-22 56 views
1

如果有像這樣的字典項的列表:如何在兩個通過列表理解分隔一個列表或以其他方式

L = [{"a":1, "b":0}, {"a":3, "b":1}...] 

我想分裂基於對「B」的值這些條目,要麼0或1.

A(b=0) = [{"a":1, "b":1}, ....] 
B(b=1) = [{"a":3, "b":2}, .....] 

我很喜歡使用簡單的列表解析,而我目前正在循環列表L兩次。

A = [d for d in L if d["b"] == 0] 
B = [d for d in L if d["b"] != 0] 

顯然這不是最有效的方法。

else子句在列表理解功能中似乎不可用。

我可以通過列表理解來做我想要的嗎?

有沒有更好的方法來做到這一點?

我正在尋找可讀性和效率之間的良好平衡,傾向於可讀性。

謝謝!

更新: 感謝大家的意見和想法!對我來說最容易閱讀的是托馬斯的那本書。但我也會看看Alex的建議。我以前沒有找到任何有關集合模塊的參考。

+0

我假設第二個代碼示例有一個鍵值爲「b」 – telliott99 2010-01-22 18:11:51

回答

4

不要使用列表理解。當您需要單個列表結果時,列表解析適用於。你顯然沒有:)使用普通的for循環:

A = [] 
B = [] 
for item in L: 
    if item['b'] == 0: 
     target = A 
    else: 
     target = B 
    target.append(item) 

你可以做,比如說,(A, B)[item['b'] != 0].append(item)縮短片段,但何必呢?

+0

的拼寫錯誤,在這種情況下,您不需要將'item ['b']'與'0'進行比較。 – SilentGhost 2010-01-22 17:28:34

+0

這取決於項目['b']的可能值是什麼,但是,通常情況下,您會使用'if item ['b']:',並交換if和else套件。 – 2010-01-22 17:30:24

3

如果b的值只能是0或1,@ Thomas的簡單解決方案可能是最好的。對於一個更一般的情況(你想區分b的幾個可能的值 - 你的樣本「預期結果」似乎完全脫離了你的問題的文本並與之相矛盾,所以你是否真的需要一些通用性並不明顯;-):

from collections import defaultdict 

separated = defaultdict(list) 
for x in L: 
    separated[x['b']].append(x) 

當該代碼執行時,separateddict結束(的collections.defaultdict實際的實例中,一個子類dict),其鍵是用於b在列表L實際發生在dict一切都值,相應的值是分開的子列表。因此,例如,如果b只需要值01,separated[0]就是您想要的列表Aseparated[1]您想要的列表B的內容(在您的問題的文本中與示例相反)。

相關問題