如何通过列表理解或其他方式将一个列表分成两个

时间:2010-01-22 17:23:43

标签: python list list-comprehension

如果有这样的字典项列表:

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子句。

我能通过列表理解做我想做的事吗?

有更好的方法吗?

我正在寻求可读性和效率之间的良好平衡,倾向于可读性。

谢谢!

更新: 感谢大家的意见和想法!对我来说最容易阅读的是托马斯的那篇。但我也会看看亚历克斯的建议。我以前没有找到任何对集合模块的引用。

2 个答案:

答案 0 :(得分:5)

不要使用列表理解。列表推导适用于您想要单个列表结果的时间。你显然不这样做:)使用常规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)来缩短代码段,但为什么要这么做呢?

答案 1 :(得分:3)

如果b值只能是0或1,@ Thomas的简单解决方案可能是最好的。对于更一般的情况(您希望区分b的几个可能值 - 您的样本“预期结果”似乎与您的问题文本完全脱节并且相矛盾,因此您是否显而易见实际上需要一些普遍性; - ):

from collections import defaultdict

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

执行此代码时,separated最终会得到一个dict(实际上是collections.defaultdict的实例,一个dict子类),其键都是{{1的值实际上发生在列表b中的dict中,相应的值是分隔的子列表。因此,例如,如果L仅采用值b0,则1将是您想要作为列表的(在您的问题的文本中而不是示例中) separated[0]A您想要的列表为separated[1]