从嵌套的dicts和列表中提取数据

时间:2014-08-25 17:30:58

标签: python list dictionary list-comprehension

说我有一个看起来像这样的字典:

dic = {'outer_key_1': {'inner_key_1': [1, 2, 3],
                       'inner_key_2': [4, 5, 6],
                       'inner_key_3': [7, 8, 9]}, 
       'outer_key_2': {'inner_key_1': [11, 12, 13],
                       'inner_key_2': [14, 15, 16],
                       'inner_key_3': [17, 18, 19]}}

我的目标是提取每个内部字典的第一个元素,最后是嵌套列表:

[[1, 4, 7], [11, 14, 17]]
或者,或者,这样的词典:

{'outer_key_1': [1, 4, 7], 'outer_key_2': [11, 14, 17]}

我尝试过使用嵌套列表推导,但我能想到的最好的是一个非嵌套的结果值列表(或多或少[1, 4, 7, 11, 14, 17]除了值混淆了,这应该是通过使用OrderedDict很容易修复)。这是一个使用for循环的相当丑陋的解决方案,但我相信这里有人可以提出更好的东西。

# TODO: find a better way to do this
result = []
for inner_dict in dic.values():
    result.append([l[0] for l in inner_dict.values()])
print(result)

打印(再一次,值混淆了,但这不是手头的问题):

[[14, 17, 11], [4, 7, 1]]

解决这个问题最优雅的方法是什么?我是python的新手,所以对如何处理这个问题的任何提示都表示赞赏。我也试过试验zip,我觉得这应该是一个非常好的方法,但我仍然需要围绕如何与列表推导一起使用,所以...任何建议?

4 个答案:

答案 0 :(得分:2)

这是一种方式:

>>> {outerKey: [innerVal[0] for innerVal in outerVal.itervalues()] for outerKey, outerVal in dic.iteritems()}
{'outer_key_1': [4, 7, 1], 'outer_key_2': [14, 17, 11]}

这是一个内部列表理解的字典理解。外部词典理解迭代外部词典的关键词对。内部列表理解列出了每个内部值中的第一个项目(即内部字典中的每个列表)。

如果你想要一个列表,只需将dict理解变为列表理解(删除对外键的引用):

>>> [[innerVal[0] for innerVal in outerVal.itervalues()] for outerKey, outerVal in dic.iteritems()]
[[14, 17, 11], [4, 7, 1]]

请注意,您无法控制列表的顺序,因为原始字典是无序的。

答案 1 :(得分:1)

默认情况下,Python中的字典不会排序。如果订单很重要,您可以在获得值之前进行排序。

result = []
for inner_dict in sorted(dic.values()):
    res = []
    for l in sorted(inner_dict.values()):
        res.append(l[0])
    result.append(res)

print(result)
# Output: [[1, 4, 7], [11, 14, 17]]

如果您需要将词典用作除此之外的排序实体,最好使用OrderedDict进行调查,默认情况下将其保持正常。

答案 2 :(得分:1)

您可以使用zip来转置值:

[ (list(zip(*d.values())[0])) for d in dic.values()]
[[14, 17, 11], [4, 7, 1]]

如果您想要排序输出:

[(list(zip(*sorted(d.values()))[0])) for d in sorted(dic.values())]

答案 3 :(得分:1)

这取决于你的优雅,但对我来说,如果你理解函数式编程,以下是相当优雅的

[zip(*e)[0] for e in map(dict.values, dic.values())]

那它做什么

  • dic.values()返回字典中的值列表
  • map(dict.values, dic.values())返回字典中的第二级嵌套值
  • 最后对于每个嵌套值列表,使用zip转置它并获取第一行,这实际上是深层嵌套字典中的第一列。

如果您想进一步优化

  1. map替换为itertools.imap
  2. 如果您仍在Python 2.X中,请将dict.values替换为dict.itervalues
相关问题