2010-01-22 21 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的内容(在您的问题的文本中与示例相反)。

相关问题