Python 中dict的有序输出(排序)

本文介绍了Python中字典的基本操作,重点讲解了如何按不同需求遍历字典,包括无序、有序及自定义顺序遍历的方法。

Python中很长用的数据结构是dict,在使用的过程中总会遇到这样的问题:你想有序的遍历一个dict

需求一,无序遍历dict中的内容,实现方式如下:

 1 None.gif# !/ usr / local / bin / python
 2 ExpandedBlockStart.gifContractedBlock.gifMAP_TEST  =   dot.gif {
 3 InBlock.gif             ' a ' : ' aa ' ,
 4 InBlock.gif             ' b ' : ' bb ' ,
 5 InBlock.gif             ' c ' : ' cc ' ,           
 6 InBlock.gif             ' d ' : ' dd ' ,
 7 ExpandedBlockEnd.gif}

 8 None.gifdef main():
 9 None.gif    for  i in MAP_TEST.keys():
10 None.gif      print i + " : " + MAP_TEST[i]
11 None.gif
12 None.gif if  __name__  ==   ' __main__ ' :
13 None.gif    main()
14 None.gif

 

需求二,有序遍历dict中的内容,但dict是无序的,所以要实现只能用list过渡

 1 None.gif# !/ usr / local / bin / python
 2 ExpandedBlockStart.gifContractedBlock.gifMAP_TEST  =   dot.gif {
 3 InBlock.gif             ' a ' : ' aa ' ,
 4 InBlock.gif             ' b ' : ' bb ' ,
 5 InBlock.gif             ' c ' : ' cc ' ,           
 6 InBlock.gif             ' d ' : ' dd ' ,
 7 ExpandedBlockEnd.gif}
 8 None.gifdef main():
 9 None.gif items  =  MAP_TEST.keys()
10 None.gif items.sort();
11 None.gif     for  i in items:
12 None.gif       print i + " : " + MAP_TEST[i]
13 None.gif
14 None.gif if  __name__  ==   ' __main__ ' :
15 None.gif    main()
16 None.gif    
17 None.gif
18 None.gif

需求三,按照自定义的顺序排列,实现如下,在sortfunc中实现你自己的排序方法
本例实现了倒序排列

 1 None.gif# !/ usr / local / bin / python
 2 ExpandedBlockStart.gifContractedBlock.gifMAP_TEST  =   dot.gif {
 3 InBlock.gif             ' a ' : ' aa ' ,
 4 InBlock.gif             ' b ' : ' bb ' ,
 5 InBlock.gif             ' c ' : ' cc ' ,           
 6 InBlock.gif             ' d ' : ' dd ' ,
 7 ExpandedBlockEnd.gif}
 8 None.gifdef sortfunc(x,y):
 9 None.gif       return  cmp(y,x);
10 None.gif   
11 None.gifdef main():
12 None.gif   items  =  MAP_TEST.keys()
13 None.gif   items.sort(sortfunc);
14 None.gif    for  i in items:
15 None.gif      print i + " : " + MAP_TEST[i]
16 None.gif
17 None.gif if  __name__  ==   ' __main__ ' :
18 None.gif    main()
19 None.gif
20 None.gif


说明:
在不通过版本的python中dict的默认顺序是不同的,编码时,特别是修改或者二次开发的时候,
应注意这个情况。可能会造成bug
例如一下四个字段,在1.5  2.2.3   2.4.3中排序不同,分别如下
1.5:
edifact
flat-encoded
vessel
flat-decoded

2.2.3:
flat-decoded
vessel
flat-encoded
edifact

Python 2.4.3
edifact
flat-decoded
flat-encoded
vessel

<think>我们参考了多个来源,总结出Python中对字典排序的几种常用方法。字典本身是无序的(Python 3.6及以后版本按插入顺序保留,但排序仍需显式操作),因此排序通常得到一个按特定顺序排列的元组列表,也可转换回有序字典(如使用`collections.OrderedDict`)。 主要方法如下: 1. **使用`sorted()`函数和`key`参数**:这是最常用的方法,通常配合`lambda`函数或`operator.itemgetter`来指定按键或按值排序。 2. **使用`zip`函数**:将字典的键和值分别取出组成两个列表,然后合并排序(多用于按值排序时同时需要键的情况)。 3. **使用字典推导式**:排序后重新构建字典(注意:Python 3.6+中字典会保持插入顺序,因此可以利用)。 4. **自定义排序函数**:封装排序逻辑以便复用。 具体实现: ### 方法1:使用`sorted()`函数和`key`参数 排序的基本步骤: - 使用`items()`方法获取键值对元组。 - 用`sorted()`函数排序,通过`key`参数指定排序依据(按键或按值)。 #### 按键排序(升序): ```python my_dict = {'b': 2, 'a': 1, 'c': 3} sorted_by_key = sorted(my_dict.items(), key=lambda x: x[0]) # 结果:[('a', 1), ('b', 2), ('c', 3)] ``` #### 按值排序(升序): ```python sorted_by_value = sorted(my_dict.items(), key=lambda x: x[1]) # 结果:[('a', 1), ('b', 2), ('c', 3)] ``` #### 降序排序: 添加参数`reverse=True`即可。 ### 方法2:使用`operator.itemgetter` 使用`itemgetter`可以提高效率,尤其在处理大数据时。 ```python import operator sorted_by_key = sorted(my_dict.items(), key=operator.itemgetter(0)) # 按键排序 sorted_by_value = sorted(my_dict.items(), key=operator.itemgetter(1)) # 按值排序 ``` ### 方法3:使用`zip`方法(按值排序) 这种方法先将字典的值和键分别取出,组成两个列表,然后使用`zip`合并,按值排序后再解压。 ```python sorted_by_value = sorted(zip(my_dict.values(), my_dict.keys())) # 得到按值排序的元组列表,每个元组是(值, 键) # 注意:如果值相同,则会根据键来排序(因为sorted是稳定的,但这里键未参与比较,若值相同,则会按原顺序?实际上这里只按值排序,相同值会按后续的键排序?不,因为zip后元组的第一项是值,第二项是键,所以当值相同时,会按第二项即键排序) ``` ### 方法4:转换为有序字典 排序后若需要字典形式,可转换为`OrderedDict`(在需要保持顺序且Python版本低于3.6时)或直接使用字典Python 3.6+)。 ```python from collections import OrderedDict # 按值排序后转为OrderedDict ordered_by_value = OrderedDict(sorted(my_dict.items(), key=lambda x: x[1])) ``` ### 方法5:自定义函数封装 如引用[5]中所示,可以定义一个函数,接受字典排序方式,返回排序后的字典。 ```python def sort_dict(d, by='key', reverse=False): if by == 'key': return dict(sorted(d.items(), key=lambda x: x[0], reverse=reverse)) elif by == 'value': return dict(sorted(d.items(), key=lambda x: x[1], reverse=reverse)) else: raise ValueError("'by' must be 'key' or 'value'") ``` ### 注意事项: - 排序后的结果通常是一个列表(元组对),若要得到字典,可用`dict()`转换(Python 3.6+保留顺序)。 - 当值相同时,排序会按照键的排序(因为`sorted`是稳定的,但初始顺序在元组比较中,若第一个元素相同则比较第二个元素,即键)。 下面是一个综合示例: ```python # 示例字典 d = {'apple': 10, 'banana': 5, 'orange': 20, 'grape': 15} # 按键升序排序 sorted_by_key = sorted(d.items(), key=lambda x: x[0]) print(sorted_by_key) # [('apple', 10), ('banana', 5), ('grape', 15), ('orange', 20)] # 按值降序排序 sorted_by_value_desc = sorted(d.items(), key=lambda x: x[1], reverse=True) print(sorted_by_value_desc) # [('orange', 20), ('grape', 15), ('apple', 10), ('banana', 5)] # 转换为字典Python 3.6+) dict_sorted_by_key = dict(sorted_by_key) print(dict_sorted_by_key) # {'apple': 10, 'banana': 5, 'grape': 15, 'orange': 20} # 使用字典推导式(按值升序排序并生成新字典) sorted_dict_by_value = {k: v for k, v in sorted(d.items(), key=lambda x: x[1])} print(sorted_dict_by_value) # {'banana': 5, 'apple': 10, 'grape': 15, 'orange': 20} ``` 以上方法覆盖了大多数字典排序场景。根据需求选择合适的方法即可。 §§相关问题§§ 1. Python字典排序时如何处理相同值的顺序? 2. 如何在较低版本的Python(如3.6以前)中保持字典有序性? 3. 除了按键和值排序,还能根据什么条件对字典排序? </think>### Python字典排序方法详解 在Python中,字典本身是无序数据结构Python 3.6+ 保留插入顺序但不应依赖),排序通常需转换为有序结构。以下是五种常用方法: #### 1. 使用`sorted()` + `lambda`(最常用) ```python my_dict = {'b': 8, 'a': 5, 'c': 3} # 按键排序(升序) sorted_by_key = sorted(my_dict.items(), key=lambda x: x[0]) # 结果: [('a', 5), ('b', 8), ('c', 3)] # 按值排序(降序) sorted_by_value = sorted(my_dict.items(), key=lambda x: x[1], reverse=True) # 结果: [('b', 8), ('a', 5), ('c', 3)] ``` #### 2. 使用`operator.itemgetter`(高效方式) ```python import operator # 按键排序 sorted_by_key = sorted(my_dict.items(), key=operator.itemgetter(0)) # 按值排序 sorted_by_value = sorted(my_dict.items(), key=operator.itemgetter(1)) ``` #### 3. 使用`zip()`方法(适合按值排序) ```python # 按值排序(升序) sorted_keys = [k for k, v in sorted(zip(my_dict.keys(), my_dict.values()), key=lambda x: x[1])] # 结果: ['c', 'a', 'b'] ``` #### 4. 字典推导式(Python 3.6+ 保留顺序) ```python # 按值升序生成新字典 sorted_dict = {k: v for k, v in sorted(my_dict.items(), key=lambda x: x[1])} # 结果: {'c': 3, 'a': 5, 'b': 8} ``` #### 5. 封装排序函数(可复用) ```python def sort_dict(d, by='key', reverse=False): if by == 'key': return dict(sorted(d.items(), key=lambda x: x[0], reverse=reverse)) else: return dict(sorted(d.items(), key=lambda x: x[1], reverse=reverse)) sorted_dict = sort_dict(my_dict, by='value', reverse=True) ``` ### 关键说明: 1. **返回值类型**:方法1-3返回`(key, value)`元组列表,需用`dict()`转为字典 2. **稳定性**:Python排序是稳定的,相同值保持原始相对顺序 3. **效率**:`operator.itemgetter`比lambda稍快(约快10-15%)[^2][^3] 4. **字典类型**:Python 3.7+ 字典正式保留插入顺序,可直接转有序字典[^5] > 示例:多层嵌套字典排序需自定义key函数,如`key=lambda x: x[1]['age']`[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值