在列表中的列表中对列表进行列表理解

时间:2014-10-26 12:56:41

标签: python list dictionary list-comprehension

我需要创建一个列表解析,从列表中的列表中的字典中提取值,到目前为止我的尝试都让我失望。该对象如下所示:

MyList=[[{'animal':'A','color':'blue'},{'animal':'B','color':'red'}],[{'animal':'C','color':'blue'},{'animal':'D','color':'Y'}]] 

我想提取dict / list / list中每个元素的值,以便获得两个新列表:

Animals=[[A,B],[C,D]]
Colors=[[blue,red],[blue,Y]]

有什么建议吗?不一定需要使用列表理解;到目前为止,这只是我的起点。谢谢!

2 个答案:

答案 0 :(得分:5)

Animals = [[d['animal'] for d in sub] for sub in MyList]
Colors = [[d['color'] for d in sub] for sub in MyList]

给出了理想的结果:

[['A', 'B'], ['C', 'D']]
[['blue', 'red'], ['blue', 'Y']]  # No second 'red'.

我在这里做的是获取每个子列表,然后是每个字典,然后访问正确的密钥。

答案 1 :(得分:1)

在单个作业中(使用单个列表理解,以及mapzip的帮助):

Colors, Animals =  map(list, 
                       zip(*[map(list, 
                                 zip(*[(d['color'], d['animal']) for d in a])) 
                             for a in MyList]))

如果您对元组没问题,可以避免两次调用map =>列表

修改

通过分解嵌套理解,让我们在一些细节中看到它。 我们还假设MyListm个元素,共有n个对象(字典)。

[[d for d in sub] for sub in MyList]

这将迭代子列表中的每个字典。对于它们中的每一个,我们在第一个元素中创建一个具有color属性的对象,在第二个元素中创建其animal属性:

(d['color'], d['animal'])

到目前为止,这需要时间与O(n)成比例 - 将处理完整的n元素。

print [[(d['color'], d['animal']) for d in sub] for sub in MyList]

现在,对于原始列表的每个m子列表,我们有一个我们需要解压缩的夫妇列表,即将其转换为两个单例列表。在Python中,使用zip函数执行 unzip ,方法是将可变数量的元组作为参数传递(第一个元组的arity确定它输出的元组数)。例如,通过3对夫妇,我们得到两个每个3个元素的列表

>>> zip((1,2), (3,4), (5,6))  #Prints [(1, 3, 5), (2, 4, 6)]

要将此应用于我们的案例,我们需要将一对夫妇传递给zip作为可变数量的参数:使用 splat 运算符完成,即{ {3}}

[zip(*[(d['color'], d['animal']) for d in sub]) for sub in MyList]

此操作需要遍历每个子列表一次,然后遍历我们在上一步中创建的每个子对。因此,总运行时间为O(n + n + m) = O(n),并且近似2*n + 2*m次操作。

到目前为止,我们有m个子列表,每个子列表包含两个元组(第一个将收集子列表的所有颜色,第二个收集所有动物的颜色)。要获得两个每个m个元组的列表,我们再次应用解压缩

zip(*[zip(*[(d['color'], d['animal']) for d in sub]) for sub in MyList]

这将需要额外的m步骤 - 因此,运行时间将保持O(n),并进行近似2*n + 4*m次操作。

为了简单起见,我们在此分析中省略了将元组映射到列表 - 如果您对元组没有问题,那就没问题了。

然而,元组是不可变的,所以情况可能并非如此。 如果您需要列表列表,则需要将list函数应用于每个元组:每个m子列表(总共2*n个元素)一次,每个元素一次2个第一级列表,即动物和颜色,(每个都有m个元素)。假设list需要的时间与应用序列的长度成比例,此额外步骤需要2*n + 2*m次操作,这仍然是O(n)