Python中列表(list)、字典(dict)排序的程序
Python3 中的排序,在 Sorting HOW TO 中已经讲得很清楚了。来个实际的例子,对下面的这个 list 依据创建时间排序:
pages = [
{'title': '十年学会程序设计', 'time': '2012-02-14', 'name': '21-days'},
{'title': 'ANE Toolkit', 'time': '2012-06-07', 'name': 'anetoolkit'},
{'title': 'cocos2d-x-filters', 'time': '2015-05-06', 'name': 'cocos2d-x-filters'},
{'title': '我的Firefox插件', 'time': '2006-05-23', 'name': 'firefox-addons'},
{'title': 'Flash&Flex大全', 'time': '2005-11-02', 'name': 'flashassistant'},
{'title': '提问的智慧', 'time': '2005-10-08', 'name': 'howtoask'},
{'title': 'Linux软件', 'time': '2009-04-30', 'name': 'linux-software'},
{'title': 'Platform ANEs', 'time': '2013-08-22', 'name': 'platform-anes'},
{'title': '阅读', 'time': '2015-03-03', 'name': 'read'},
{'title': 'Sprite Sheet Editor', 'time': '2011-08-18', 'name': 'sprite_sheet_editor'},
{'title': 'SpriteSheetPacker', 'time': '2011-04-19', 'name': 'spritesheetpacker'},
{'title': 'WordPress大全', 'time': '2006-03-07', 'name': 'wordpressfavorite'},
{'title': 'WPCMD', 'time': '2015-06-12', 'name': 'wpcmd'}
]
首先,排序需要一个可以比较的对象,我使用键名为 index 中的对象:
from datetime import date
for item in pages:
t = item['time'].split('-')
item['index'] = date(int(t[0]), int(t[1]), int(t[2]))
date 的实例是可比较的(它实现了 __lt__ 那一套方法), date(2012,2,14) < data(2005, 11, 2) == False 。
然后,对 pages 调用 sort 方法:
pages.sort(key=lambda item : item['index'])
在这里,我需要为 key 传递一个函数,这个函数能返回需要比较的值。
当然,也可以使用 operator 提供的 itemgetter 方法来获取这个待比较的值。
from operator import itemgetter
names.sort(key=itemgetter('index'))
除了 itemgetter 之外, operator 模块还提供了 attrgetter 和 methodcaller 。
张贺 对上面提到的 Sorting Mini-HOW TO 做了一些必要的中文评注,该文和 Sorting HOW TO 基本相同。
通过某个关键字排序一个字典列表
通过使用operator模块的itemgetter函数,可以非常容易的排序这样的数据结构。 假设你从数据库中检索出来网站会员信息列表,并且以下列的数据结构返回:
rows = [
{'fname': 'Brian', 'lname': 'Jones', 'uid': 1003},
{'fname': 'David', 'lname': 'Beazley', 'uid': 1002},
{'fname': 'John', 'lname': 'Cleese', 'uid': 1001},
{'fname': 'Big', 'lname': 'Jones', 'uid': 1004}
]
根据任意的字典字段来排序输入结果行是很容易实现的,代码示例:
from operator import itemgetter
rows_by_fname = sorted(rows, key=itemgetter('fname'))
rows_by_uid = sorted(rows, key=itemgetter('uid'))
print(rows_by_fname)
print(rows_by_uid)
代码的输出如下:
[{'fname': 'Big', 'uid': 1004, 'lname': 'Jones'},
{'fname': 'Brian', 'uid': 1003, 'lname': 'Jones'},
{'fname': 'David', 'uid': 1002, 'lname': 'Beazley'},
{'fname': 'John', 'uid': 1001, 'lname': 'Cleese'}]
[{'fname': 'John', 'uid': 1001, 'lname': 'Cleese'},
{'fname': 'David', 'uid': 1002, 'lname': 'Beazley'},
{'fname': 'Brian', 'uid': 1003, 'lname': 'Jones'},
{'fname': 'Big', 'uid': 1004, 'lname': 'Jones'}]
itemgetter()函数也支持多个keys,比如下面的代码
rows_by_lfname = sorted(rows, key=itemgetter('lname','fname'))
print(rows_by_lfname)
会产生如下的输出:
[{'fname': 'David', 'uid': 1002, 'lname': 'Beazley'},
{'fname': 'John', 'uid': 1001, 'lname': 'Cleese'},
{'fname': 'Big', 'uid': 1004, 'lname': 'Jones'},
{'fname': 'Brian', 'uid': 1003, 'lname': 'Jones'}]
讨论
在上面例子中,rows 被传递给接受一个关键字参数的 sorted() 内置函数。 这个参数是 callable 类型,并且从 rows 中接受一个单一元素,然后返回被用来排序的值。 itemgetter() 函数就是负责创建这个 callable 对象的。
operator.itemgetter() 函数有一个被rows中的记录用来查找值的索引参数。可以是一个字典键名称, 一个整形值或者任何能够传入一个对象的 __getitem__() 方法的值。 如果你传入多个索引参数给 itemgetter() ,它生成的 callable 对象会返回一个包含所有元素值的元组, 并且sorted()函数会根据这个元组中元素顺序去排序。 但你想要同时在几个字段上面进行排序(比如通过姓和名来排序,也就是例子中的那样)的时候这种方法是很有用的。
itemgetter() 有时候也可以用lambda表达式代替,比如:
rows_by_fname = sorted(rows, key=lambda r: r['fname'])
rows_by_lfname = sorted(rows, key=lambda r: (r['lname'],r['fname']))
这种方案也不错。但是,使用itemgetter()方式会运行的稍微快点。因此,如果你对性能要求比较高的话就使用itemgetter()方式。
最后,不要忘了这节中展示的技术也同样适用于min()和max()等函数。比如:
>>> min(rows, key=itemgetter('uid'))
{'fname': 'John', 'lname': 'Cleese', 'uid': 1001}
>>> max(rows, key=itemgetter('uid'))
{'fname': 'Big', 'lname': 'Jones', 'uid': 1004}
>>>
排序不支持原生比较的对象
内置的 sorted() 函数有一个关键字参数 key ,可以传入一个 callable 对象给它, 这个 callable 对象对每个传入的对象返回一个值,这个值会被 sorted 用来排序这些对象。 比如,如果你在应用程序里面有一个User实例序列,并且你希望通过他们的user_id属性进行排序, 你可以提供一个以User实例作为输入并输出对应user_id值的 callable 对象。比如:
class User:
def __init__(self, user_id):
self.user_id = user_id
def __repr__(self):
return 'User({})'.format(self.user_id)
def sort_notcompare():
users = [User(23), User(3), User(99)]
print(users)
print(sorted(users, key=lambda u: u.user_id))
另外一种方式是使用 operator.attrgetter() 来代替lambda函数:
>>> from operator import attrgetter
>>> sorted(users, key=attrgetter('user_id'))
[User(3), User(23), User(99)]
>>>
讨论
选择使用lambda函数或者是 attrgetter() 可能取决于个人喜好。 但是,attrgetter() 函数通常会运行的快点,并且还能同时允许多个字段进行比较。 这个跟 operator.itemgetter() 函数作用于字典类型很类似(参考1.13小节)。 例如,如果User实例还有一个first_name和last_name属性,那么可以向下面这样排序:
by_name = sorted(users, key=attrgetter('last_name', 'first_name'))
同样需要注意的是,这一小节用到的技术同样适用于像 min() 和 max() 之类的函数。比如:
>>> min(users, key=attrgetter('user_id')
User(3)
>>> max(users, key=attrgetter('user_id')
User(99)
>>>
Python中列表(list)、字典(dict)排序的程序的更多相关文章
- python中列表和字典常用方法和函数
Python列表函数&方法 Python包含以下函数: 序号 函数 1 cmp(list1, list2)比较两个列表的元素 2 len(list)列表元素个数 3 max(list)返回列表 ...
- **python中列表 元组 字典 集合
列表 元组 字典 集合的区别是python面试中最常见的一个问题.这个问题虽然很基础,但确实能反映出面试者的基础水平. 1.列表 列表是以方括号“[]”包围的数据集合,不同成员以“,”分隔. 列表的特 ...
- python 中列表 元组 字典 集合的区别
先看图片解释 (1)列表 什么是列表呢?我觉得列表就是我们日常生活中经常见到的清单.比如,统计过去一周我们买过的东西,把这些东西列出来,就是清单.由于我们买一种东西可能不止一次,所以清单中是允许有重复 ...
- python中列表 元组 字典 集合的区别
列表 元组 字典 集合的区别是python面试中最常见的一个问题.这个问题虽然很基础,但确实能反映出面试者的基础水平. (1)列表 什么是列表呢?我觉得列表就是我们日常生活中经常见到的清单.比如,统计 ...
- Python中常见的字典dict处理
#字典的赋值d = [{"dasda": 123, "gsgsg": 3344}, {"dasdz": 123, "gsksg&q ...
- python中列表和字典的高级应用
1.将序列分解为单独的变量 1.1问题 包含n个元素的元组或列表.字符串.文件.迭代器.生成器,将它分解为n个变量 1.2方案 直接通过赋值操作 要求:变量个数要等于元素个数 当执行分解操作时,有时需 ...
- Python中列表,元组,字典,集合的区别
参考文档https://blog.csdn.net/Yeoman92/article/details/56289287 理解Python中列表,元组,字典,集合的区别 列表,元组,字典,集合的区别是p ...
- Python学习-列表元组字典操作
一.列表 列表是Python的基本数据类型之一,它是以 [] 括起来的,内部成员用逗号隔开.里面可以存放各种数据类型. # 例如: list2 = ['jason', 2, (1, 3), ['war ...
- python中列表和元组以及字符串的操作
python中列表是非常好用的.不过有一些使用小细节还需要注意一下. tag[32:-4] 从index为32到tag的倒数第4个字符. 如果索引为32的值在倒数第4个字符的右边,那么将输出为空.只要 ...
随机推荐
- 20165326 学习基础和c语言基础调查
学习基础和c语言基础调查 一.关于个人技能 阅读了娄老师关于做中学的文章,我想起了自己之前学习技能的经历. 从小到大我学过的东西不少,除学校的教育课程外,我还参加过各种兴趣班,书法.绘画.舞蹈.吉他. ...
- Word2Vec实现原理(Hierarchical Softmax)
由于word2vec有两种改进方法,一种是基于Hierarchical Softmax的,另一种是基于Negative Sampling的.本文关注于基于Hierarchical Softmax的改进 ...
- golang对数组进行冒泡排序
什么是冒泡排序? 冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法. 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地 ...
- LeetCode--122、167、169、189、217 Array(Easy)
122. Best Time to Buy and Sell Stock II Say you have an array for which the ith element is the price ...
- wx小程序修改swiper 点的样式
<swiper class="swiper-box" indicator-dots="{{ indicatordots }}" autoplay=&quo ...
- Spring Boot 揭秘与实战(二) 数据存储篇 - 数据访问与多数据源配置
文章目录 1. 环境依赖 2. 数据源 3. 单元测试 4. 源代码 在某些场景下,我们可能会在一个应用中需要依赖和访问多个数据源,例如针对于 MySQL 的分库场景.因此,我们需要配置多个数据源. ...
- Oracle自我补充之OVER()函数介绍
OVER(PARTITION BY)函数介绍 开窗函数 Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是:对于每个组返 ...
- [link] 构建负载均衡服务器之一 负载均衡与集群详解
一.什么是负载均衡 首先我们先介绍一下什么是负载均衡: 负载平衡(Load balancing)是一种计算机网络技术,用来在多个计算机(计算机集群).网络连接.CPU.磁盘驱动器或其他资源中分配负载, ...
- skflow 分类与回归接口API 简单测试
skflow也即是 tf.contrib.learn, 是 TensorFlow 官方提供的另外一个对 TensorFlow 的高层封装,通过这个封装,用户可以和使用 sklearn 类似的方法使用 ...
- NOI-1.1-08-字符三角形
08:字符三角形 总时间限制: 1000ms 内存限制: 65536kB 描述 给定一个字符,用它构造一个底边长5个字符,高3个字符的等腰字符三角形. 输入 输入只有一行, 包含一个字符. 输出 ...