按嵌套Di列表中的值对Dict排序

2024-09-29 06:31:06 发布

您现在位置:Python中文网/ 问答频道 /正文

这已经让我抓狂了好几天了,我看到了一些关于按值排序dict的问题,但它们的结构很简单,我的很复杂。你知道吗

我的顶级Dict键是散列,sub Dict键是序列#,sub 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"

我希望能够按照这个值对dict进行正向和反向排序。我看到了:

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

我不知道如何将其应用于我的问题,通常我的尝试以KeyError:1或IndexError:string超出范围而告终。你知道吗

我错过了什么? 如何引用lamba的值? 这就是我要做的吗?你知道吗

我不喜欢使用包含熊猫的解决方案。我正在努力使它快速/高效,因为数据可能相当大(目前有10000个子键)

编辑:

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

 {'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]}}

Tags: 列表data排序items结构顶级dictlist
2条回答

你的问题有点不清楚,我的理解是你有{k1: {k2: [v1, v2, v3, v4]}},你想按v4对每个顶级条目进行排序,每个列表中的条目应该是相同的(所以我们选择哪个并不重要)。但是,子条目(k2)在顶级条目之间不是常量。你知道吗

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

所以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,可能是Python3.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]}}

这里有一个丑陋的(相当低效的)变种。它结合了dict理解、排序,并获得对应于键的1stdict值(通过(丑陋的)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'])

因为12ndone)只存在于'16741b673a418af3812f6d43ea3f7daf'的子字典中。你知道吗

你的字典里有大量的重复。它可以被精简为以下内容(也使排序表达式更加简单):

>>> data = {("16741b673a418af3812f6d43ea3f7daf", 1132): ["data-01", "data-02", "data-03"],
...         ("cbef6de99cc2b9739c824db6d0246093", 55296): ["data-04", "data-05", "data-06", "data-07"],
...         ("a1e0f7ccdd8d38cb5ae00cdac71b6724", 20125): ["data-08", "data-09", "data-10"]}
>>>
>>> {k: v for k, v in sorted(data.items(), key=lambda x: x[0][1])}

相关问题 更多 >