按嵌套字典列表中的值对字典排序

时间:2019-04-12 05:58:12

标签: python dictionary

几天来,这一直困扰着我,我已经看到了有关按值对Dict进行排序的几个问题,但是它们结构简单,而我的却很复杂。

我的顶级Dict Key是一个哈希,子Dict Key是一个序列号,而子Dict值是一个列表。其中的最后一个值是一个数字,这就是我要按顶级Dict排序的内容。 Dict的大小可能很大,但这是一个示例:

 {'16741b673a418af3812f6d43ea3f7daf': 
    {1: [0, '16741b673a418af3812f6d43ea3f7daf', 'data-01', 1132],
     2: [1, '16741b673a418af3812f6d43ea3f7daf', 'data-02', 1132],
     3: [2, '16741b673a418af3812f6d43ea3f7daf', 'data-03', 1132]},

 'cbef6de99cc2b9739c824db6d0246093':
    {4: [0, 'cbef6de99cc2b9739c824db6d0246093', 'data-04', 55296],
     5: [1, 'cbef6de99cc2b9739c824db6d0246093', 'data-05', 55296],
     6: [1, 'cbef6de99cc2b9739c824db6d0246093', 'data-06', 55296],
     7: [2, 'cbef6de99cc2b9739c824db6d0246093', 'data-07', 55296]},
 'a1e0f7ccdd8d38cb5ae00cdac71b6724':
    {8: [0, 'a1e0f7ccdd8d38cb5ae00cdac71b6724', 'data-08', 20125],
     9: [1, 'a1e0f7ccdd8d38cb5ae00cdac71b6724', 'data-09', 20125],
    10: [1, 'a1e0f7ccdd8d38cb5ae00cdac71b6724', 'data-10', 20125]}}

这段代码将为我提供所需的值,但仅在第一次迭代时,我会得到 KeyError:1

for item1 in mydict.items():
    print(item1[1][1][3])

item1[1] returns subkey 1's list
item1[2] returns subkey 2's list
item1[3] returns subkey 3's list
item1[1][1][3] returns subkey 1's "value"

我希望能够根据该值对字典进行正向和反向排序。我看过:

sorted(data.items(), key=lambda x:x[1])

我不知道如何将其应用于我的问题,通常我的尝试最终会导致KeyError:1或IndexError:字符串超出范围。

我想念什么? 我该如何参考兰巴舞的价值? 那是我需要做的吗?

我不希望使用包含熊猫的解决方案。由于数据可能很大(目前有10,000个子键),因此我试图使其快速/高效。

编辑:

输出看起来相同,但按列表中的最后一个值排序:

 {'16741b673a418af3812f6d43ea3f7daf': 
    {1: [0, '16741b673a418af3812f6d43ea3f7daf', 'data-01', 1132],
     2: [1, '16741b673a418af3812f6d43ea3f7daf', 'data-02', 1132],
     3: [2, '16741b673a418af3812f6d43ea3f7daf', 'data-03', 1132]},

 'a1e0f7ccdd8d38cb5ae00cdac71b6724':
    {8: [0, 'a1e0f7ccdd8d38cb5ae00cdac71b6724', 'data-08', 20125],
     9: [1, 'a1e0f7ccdd8d38cb5ae00cdac71b6724', 'data-09', 20125],
    10: [1, 'a1e0f7ccdd8d38cb5ae00cdac71b6724', 'data-10', 20125]},

 'cbef6de99cc2b9739c824db6d0246093':
    {4: [0, 'cbef6de99cc2b9739c824db6d0246093', 'data-04', 55296],
     5: [1, 'cbef6de99cc2b9739c824db6d0246093', 'data-05', 55296],
     6: [1, 'cbef6de99cc2b9739c824db6d0246093', 'data-06', 55296],
     7: [2, 'cbef6de99cc2b9739c824db6d0246093', 'data-07', 55296]}}

2 个答案:

答案 0 :(得分:2)

您的问题有点不清楚,据我了解,您有{k1: {k2: [v1, v2, v3, v4]}},您想按v4对每个顶级条目进行排序,因此每个列表中的条目都应该相同(因此,不管我们选哪个)。但是,子条目(k2)在顶级条目之间不是恒定的。

从子条目获取v4很容易([3][-1]),问题是获取第二级字典的任意值。 next(iter(d.values()))应该这样做:迭代子值(列表),并从迭代器中获取第一个值。这并不是说如果子条目为空(顶级键映射为空字典)会引发错误。

因此sorted(data.items(), key=lambda e: next(iter(e[1].values()))[-1])应该起作用:

[('16741b673a418af3812f6d43ea3f7daf',
  {1: [0, '16741b673a418af3812f6d43ea3f7daf', 'data-01', 1132],
   2: [1, '16741b673a418af3812f6d43ea3f7daf', 'data-02', 1132],
   3: [2, '16741b673a418af3812f6d43ea3f7daf', 'data-03', 1132]}),
 ('a1e0f7ccdd8d38cb5ae00cdac71b6724',
  {8: [0, 'a1e0f7ccdd8d38cb5ae00cdac71b6724', 'data-08', 20125],
   9: [1, 'a1e0f7ccdd8d38cb5ae00cdac71b6724', 'data-09', 20125],
   10: [1, 'a1e0f7ccdd8d38cb5ae00cdac71b6724', 'data-10', 20125]}),
 ('cbef6de99cc2b9739c824db6d0246093',
  {4: [0, 'cbef6de99cc2b9739c824db6d0246093', 'data-04', 55296],
   5: [1, 'cbef6de99cc2b9739c824db6d0246093', 'data-05', 55296],
   6: [1, 'cbef6de99cc2b9739c824db6d0246093', 'data-06', 55296],
   7: [2, 'cbef6de99cc2b9739c824db6d0246093', 'data-07', 55296]})]

请注意,这将返回(key, value)元组的列表,而不是字典。您必须将其反馈到dict(最好是OrderedDict,可能是Python 3.6或更高版本中的常规dict)以保持顺序:

{'16741b673a418af3812f6d43ea3f7daf': 
   {1: [0, '16741b673a418af3812f6d43ea3f7daf', 'data-01', 1132],
    2: [1, '16741b673a418af3812f6d43ea3f7daf', 'data-02', 1132],
    3: [2, '16741b673a418af3812f6d43ea3f7daf', 'data-03', 1132]},
 'a1e0f7ccdd8d38cb5ae00cdac71b6724': 
   {8: [0, 'a1e0f7ccdd8d38cb5ae00cdac71b6724', 'data-08', 20125],
    9: [1, 'a1e0f7ccdd8d38cb5ae00cdac71b6724', 'data-09', 20125],
    10: [1, 'a1e0f7ccdd8d38cb5ae00cdac71b6724', 'data-10', 20125]},
 'cbef6de99cc2b9739c824db6d0246093': {
    4: [0, 'cbef6de99cc2b9739c824db6d0246093', 'data-04', 55296],
    5: [1, 'cbef6de99cc2b9739c824db6d0246093', 'data-05', 55296],
    6: [1, 'cbef6de99cc2b9739c824db6d0246093', 'data-06', 55296],
    7: [2, 'cbef6de99cc2b9739c824db6d0246093', 'data-07', 55296]}}

答案 1 :(得分:0)

这是一个丑陋(且效率很低)的变体。它结合了 dict 理解,排序和获取对应于键的1 st dict 值(通过(丑陋的){{ 1}}):

d[list(d.keys())[0]]

您在>>> data.keys() dict_keys(['16741b673a418af3812f6d43ea3f7daf', 'cbef6de99cc2b9739c824db6d0246093', 'a1e0f7ccdd8d38cb5ae00cdac71b6724']) >>> data_sorted = {k: v for k, v in sorted(data.items(), key=lambda x: x[1][list(x[1].keys())[0]][3])} >>> data_sorted.keys() dict_keys(['16741b673a418af3812f6d43ea3f7daf', 'a1e0f7ccdd8d38cb5ae00cdac71b6724', 'cbef6de99cc2b9739c824db6d0246093']) 中出现了 KeyError ,因为 1 第二个 nd 一个)仅存在于item1[1][1][3]的子词典中。

您的 dict 包含大量重复项。可以将其修剪成类似(也使排序表达式更简单):

'16741b673a418af3812f6d43ea3f7daf'