python - 按最频繁的字段对 namedtupled 列表进行排序
问题描述
有哪些优雅而快速的简单方法可以按列表中namedtuple
最常见的元素对列表进行排序?
例如,我们有这个列表
character_list = [
Element(id=1, character='A'),
Element(id=2, character='B'),
Element(id=3, character='B'),
Element(id=4, character='C'),
Element(id=5, character='D'),
Element(id=6, character='E'),
Element(id=7, character='F'),
Element(id=8, character='H'),
Element(id=9, character='I'),
Element(id=10, character='J'),
Element(id=11, character='K'),
Element(id=12, character='L'),
Element(id=13, character='M'),
Element(id=14, character='J'),
Element(id=15, character='N'),
Element(id=16, character='J')]
并这样排序?
character_list = [
Element(id=10, character='J'),
Element(id=14, character='J'),
Element(id=16, character='J'),
Element(id=2, character='B'),
Element(id=3, character='B'),
Element(id=1, character='A'),
Element(id=4, character='C'),
Element(id=5, character='D'),
Element(id=6, character='E'),
Element(id=7, character='F'),
Element(id=8, character='H'),
Element(id=9, character='I'),
Element(id=11, character='K'),
Element(id=12, character='L'),
Element(id=13, character='M'),
Element(id=14, character='J'),
Element(id=15, character='N')]
试试这个,但似乎没有我要找的结果
sorted(character_list, key=lambda x: character_list.count(x.character))
解决方案
x.character
永远不在您的列表中。无论如何,list.count
像这样使用是非常低效的。排序是 O(N*log N),但是,如果你的 key-function 使用list.count
,它将使一切恶化到 O(N**2)。
相反,构建一个计数字典并使用该字典,这将保持您的 O(N*log N) 性能。所以给出:
>>> from pprint import pprint
>>> pprint(character_list)
[Element(id=1, character='A'),
Element(id=2, character='B'),
Element(id=3, character='B'),
Element(id=4, character='C'),
Element(id=5, character='D'),
Element(id=6, character='E'),
Element(id=7, character='F'),
Element(id=8, character='H'),
Element(id=9, character='I'),
Element(id=10, character='J'),
Element(id=11, character='K'),
Element(id=12, character='L'),
Element(id=13, character='M'),
Element(id=14, character='J'),
Element(id=15, character='N'),
Element(id=16, character='J')]
然后
>>> from collections import Counter
>>> counts = Counter(e.character for e in character_list)
>>> counts
Counter({'J': 3, 'B': 2, 'A': 1, 'C': 1, 'D': 1, 'E': 1, 'F': 1, 'H': 1, 'I': 1, 'K': 1, 'L': 1, 'M': 1, 'N': 1})
最后,
>>> def keyfunc(e):
... return counts[e.character]
...
>>> sorted_character_list = sorted(character_list, key=keyfunc, reverse=True)
>>> pprint(sorted_character_list)
[Element(id=10, character='J'),
Element(id=14, character='J'),
Element(id=16, character='J'),
Element(id=2, character='B'),
Element(id=3, character='B'),
Element(id=1, character='A'),
Element(id=4, character='C'),
Element(id=5, character='D'),
Element(id=6, character='E'),
Element(id=7, character='F'),
Element(id=8, character='H'),
Element(id=9, character='I'),
Element(id=11, character='K'),
Element(id=12, character='L'),
Element(id=13, character='M'),
Element(id=15, character='N')]
推荐阅读
- python - 从 Python 调用时与 openssl 的结果不一致
- ajax - Webix:更新树形菜单数据的 AJAX 响应
- constraints - 基于 System Verilog 中运行时数据的加权随机化
- sql - 如何在 SQL 中对数字进行四舍五入
- vmware-clarity - 为 1.0 版自定义 Clarity 主题
- java - 从网页获取 Java 或 C 程序的输入?
- c++ - Python实现不适用于c ++中的相同逻辑
- javascript - 在鼠标右键单击时禁用上下文菜单
- python - pip 安装前的 conda
- html - 尽管 Div 大小保持边界半径一致