鱼C论坛

 找回密码
 立即注册
查看: 810|回复: 15

[已解决]关于字典排序的问题

[复制链接]
发表于 2021-2-26 17:47:43 From FishC Mobile | 显示全部楼层 |阅读模式
10鱼币
请问各位大佬关于下面这种类型的字典的key排序该如何解决呢?

字典的key格式如下 value的值都不一样 以下全部省略为xxx
sample = {‘1_a’: xxx, ‘1_b’: xxx, ‘1_k’: xxx, ‘2_a’:xxx, ‘2_b’: xxx, ‘2_k’:xxx, ‘3_a’: xxx, ‘3_b’:xxx, ‘3_k’: xxx, .......}

希望得到如下结果  n_a的key在最前面 其次为n_k,最后是n_b的key
result = {‘1_a’:xxx, ‘2_a': xxx, ‘3_a’:xxx ,‘1_k’:xxx, ‘2_k’: xxx, ‘3_k’: xxx, ‘1_b’: xxx, .....}
最佳答案
2021-2-26 17:47:44
本帖最后由 hrp 于 2021-2-27 12:06 编辑
snowzkr 发表于 2021-2-27 00:57
谢谢 不过感觉结果不太对 希望得到的结果是下面这样.  _k的key要在_b前面比较头疼
{‘1_a': 123, '2_a’ ...


键的数字是按升序排序,但是字母部分既不是升序也不是降序排列,你也没给排序规则或者算法,只能自定义一个顺序表去排序了。

  1. # coding: utf-8

  2. import re

  3. sample = {'1_a': 123, '1_b': 456, '1_k': 789, '2_a': 12, '2_b': 34, '2_k': 56, '3_a': 78, '3_b':90, '3_k': 1}

  4. # 自定义顺序, 可根据需要进行更改
  5. order = 'a', 'k', 'b'

  6. def sortkey(s):
  7.     s = s[0]
  8.     lto = re.search(r'_([a-z]+)$', s)
  9.     if not lto:
  10.         return s[::-1]
  11.     lt = lto.group(1)
  12.     if lt in order:
  13.         return s.replace(lto.group(0), str(order.index(lt)))[::-1]
  14.     return s[::-1]

  15. sample = dict(sorted(sample.items(), key=sortkey))

  16. print(sample)
复制代码

最佳答案

查看完整内容

键的数字是按升序排序,但是字母部分既不是升序也不是降序排列,你也没给排序规则或者算法,只能自定义一个顺序表去排序了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2021-2-26 17:47:44 From FishC Mobile | 显示全部楼层    本楼为最佳答案   
本帖最后由 hrp 于 2021-2-27 12:06 编辑
snowzkr 发表于 2021-2-27 00:57
谢谢 不过感觉结果不太对 希望得到的结果是下面这样.  _k的key要在_b前面比较头疼
{‘1_a': 123, '2_a’ ...


键的数字是按升序排序,但是字母部分既不是升序也不是降序排列,你也没给排序规则或者算法,只能自定义一个顺序表去排序了。

  1. # coding: utf-8

  2. import re

  3. sample = {'1_a': 123, '1_b': 456, '1_k': 789, '2_a': 12, '2_b': 34, '2_k': 56, '3_a': 78, '3_b':90, '3_k': 1}

  4. # 自定义顺序, 可根据需要进行更改
  5. order = 'a', 'k', 'b'

  6. def sortkey(s):
  7.     s = s[0]
  8.     lto = re.search(r'_([a-z]+)$', s)
  9.     if not lto:
  10.         return s[::-1]
  11.     lt = lto.group(1)
  12.     if lt in order:
  13.         return s.replace(lto.group(0), str(order.index(lt)))[::-1]
  14.     return s[::-1]

  15. sample = dict(sorted(sample.items(), key=sortkey))

  16. print(sample)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2021-2-26 20:38:48 | 显示全部楼层
字典为什么要排序?你是对字典有什么误解吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2021-2-26 21:07:24 | 显示全部楼层
我只能把键排个序,剩下的也不知怎么办
  1. d = {'b_0':'XXX', 'a_2':'XXX', 'a_3':'XXX', 'b_1':'XXX', 'b_2':'XXX'}
  2. def keysintide(d):
  3.         list_ = []
  4.         for k, v in d.items():
  5.                 list_.append(k)
  6.         list_.sort()
  7.         return list_
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2021-2-26 21:27:19 From FishC Mobile | 显示全部楼层
本帖最后由 hrp 于 2021-2-26 21:49 编辑

Python3.6以前字典是无序的,3.6及以后的版本,字典可以保持创建时的顺序。
  1. # coding: utf-8

  2. sample = {'1_a': 123, '1_b': 456, '1_k': 789, '2_a': 12, '2_b': 34, '2_k': 56, '3_a': 78, '3_b':90, '3_k': 1}
  3. sample = dict(sorted(sample.items(), key=lambda x: x[0][::-1]))

  4. print(sample)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2021-2-26 21:36:28 | 显示全部楼层
from collections import OrderedDict

sample = {'1_a': 123, '1_b': 456, '1_k': 789, '2_a': 12, '2_b': 34, '2_k': 56, '3_a': 78, '3_b':90, '3_k': 1}

o_sample  = OrderedDict(sorted(data.items(), key=lambda x: x[0]))

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2021-2-26 21:38:10 | 显示全部楼层
当然 python高版本字典已经可以代替OrderedDict了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2021-2-27 00:51:59 From FishC Mobile | 显示全部楼层
本帖最后由 snowzkr 于 2021-2-27 01:18 编辑
洋洋痒 发表于 2021-2-26 20:38
字典为什么要排序?你是对字典有什么误解吗


上面需求是这样…最终的值是以json形式给前端去处理的。所以也没有办法 只能按需求去整
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2021-2-27 00:57:41 From FishC Mobile | 显示全部楼层
hrp 发表于 2021-2-26 21:27
Python3.6以前字典是无序的,3.6及以后的版本,字典可以保持创建时的顺序。

谢谢 不过感觉结果不太对 希望得到的结果是下面这样.  _k的key要在_b前面比较头疼
{‘1_a': 123, '2_a’: 12, '3_a': 78, '1_k’: xxx, '2_k': xxx, '3_k': xxx, '1_b': xxx, '2_b':xxx, '3_b': xxx}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2021-2-27 01:01:18 From FishC Mobile | 显示全部楼层
柿子饼同学 发表于 2021-2-26 21:07
我只能把键排个序,剩下的也不知怎么办

感谢 _k的key要在_b的key的前面这个问题比较麻烦。不知道有什么好的办法
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2021-2-27 01:09:07 From FishC Mobile | 显示全部楼层
kogawananari 发表于 2021-2-26 21:36
from collections import OrderedDict

sample = {'1_a': 123, '1_b': 456, '1_k': 789, '2_a': 12, '2_b ...

谢谢 不过希望得到的结果是
{'1_a': 123, '2_a': 12, '3_a': 78,  '1_k': 789, '2_k’: 56, '3_k': 1, '1_b': 456, '3_b':34, '3_b': 90}


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2021-2-27 01:39:32 | 显示全部楼层
有一个想法

请看到最后,这是一个没有办法的办法,先变成数组再 sort,然后填入一个新的字典

可以使用数组的 sort 方法,先把键和值提取出来

塞进一个列表里,然后使用 sort 方法排序

再取出列表里面的键和值,生成一个新的字典

新生成的字典就是按照顺序的

截屏2021-02-27 01.36.37.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2021-2-27 01:50:22 | 显示全部楼层
Daniel_Zhang 发表于 2021-2-27 01:39
有一个想法

请看到最后,这是一个没有办法的办法,先变成数组再 sort,然后填入一个新的字典
  1. # coding: utf-8

  2. list1 = []
  3. new_dict = {}
  4. sample = {'1_a': 123, '2_d': 111, '1_b': 456, '1_k': 789, '2_a': 12,
  5.           '2_b': 34, '2_k': 56, '3_a': 78, '8_b': 12, '3_b': 90, '3_k': 1}

  6. for key, value in sample.items():
  7.     list2 = []
  8.     list2.extend([key, value])
  9.     list1.append(list2)

  10. list1.sort()
  11. print(list1)

  12. for each in range(len(list1)):
  13.     new_dict[list1[each][0]] = list1[each][1]

  14. print(new_dict)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2021-2-27 03:10:06 | 显示全部楼层
本帖最后由 kogawananari 于 2021-2-27 03:13 编辑
snowzkr 发表于 2021-2-27 01:01
感谢 _k的key要在_b的key的前面这个问题比较麻烦。不知道有什么好的办法


按照'_'分割数组 倒置后排序

  1. sample = {'1_a': 123, '2_d': 111, '1_b': 456, '1_k': 789, '2_a': 12,
  2.           '2_b': 34, '2_k': 56, '3_a': 78, '8_b': 12, '3_b': 90, '3_k': 1}

  3. new_dict = dict(sorted(sample.items(), key=lambda x: "".join(x[0].split('_')[::-1])))

  4. print(new_dict)
复制代码


满意没
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2021-2-27 18:19:39 From FishC Mobile | 显示全部楼层
下面这样写法可以得到想要的结果…
_a的键在最前 其次为_k的键 最后是_b的键的顺序。 不过写法套了2个循环。 不知可否有什么优化的写法 望大神们指点。

from collections import OrderedDict

sample = {'1_a': 123, '2_k': 12, '3_a': 78,  '1_k': 789, '2_b': 56, '3_b':123, '1_b': 456, '2_a':34, '3_k': 90}
target_list = ['a', 'k', 'b']
json_dict = OrderedDict()
for i in target_list:
    for k,v in sample.items():
        if k.endswith(i):
            json_dict.update({k:v})

print(json_dict)


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2021-2-27 19:58:30 | 显示全部楼层
本帖最后由 Stubborn 于 2021-2-27 20:04 编辑

*a -> *k ->*b  
只需要分类还是分类之后,还要在排序?
先分类,然后在用sorted进行key的排序,然后用有序字典OrderedDict类添加把

  1. >>> a = {'1_a':1, '3_a':2, '2_a':3}
  2. >>> sorted(a.keys())
  3. ['1_a', '2_a', '3_a']
复制代码

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1

GMT+8, 2023-2-9 11:16

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表