说我有一个看起来像这样的字典:
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
,我觉得这应该是一个非常好的方法,但我仍然需要围绕如何与列表推导一起使用,所以...任何建议?
答案 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
转置它并获取第一行,这实际上是深层嵌套字典中的第一列。如果您想进一步优化
map
替换为itertools.imap
dict.values
替换为dict.itervalues