[PY3]——求TopN/BtmN 和 排序问题的解决
需求
K长的序列,求TopN
K长的序列,求BtmN
排序问题
解决
- heap.nlargest()、heap.nsmallest( )
- sorted( )+切片
- max( )、min( )
总结和比较
1)在Top N问题中,如果 N=1,则直接用max(iterable)/min(iterable) 即可(效率最高)。
2)如果N很大,接近集合元素,则为了提高效率,采用 sort+切片 的效率会更高,如:
求最大的N个元素:sorted(iterable, key=key, reverse=True)[:N]
求最小的N个元素:sorted(iterable, key=key)[:N]
3)当要查找的元素个数相对比较小的时候,使用 nlargest() 和 nsmallest() 是很合适的
详解max( )/min( )函数用法
- 求简单的序列TopN/BtmN(N=1)问题
lst=[1,2,3,4,5]
print(max(lst))
5
- 通过key属性的使用,设置函数条件为判断的标准
a=[-9,-8,1,3,-4,6]
print(max(a,key=lambda x:abs(x)))
-9
- 找出字典中值最大的那组数据
prices = {
'A':123,
'B':450.1,
'C':12,
'E':444,
}
//在对字典进行数据操作的时候,默认只会处理key,而不是value
//先使用zip把字典的keys和values翻转过来,再用max取出值最大的那组数据
max_prices=max(zip(prices.values(),prices.keys()))
print(max_prices)
(450.1, 'B')
nlargest( )/nsmallest( )详解
- nlargest(n,iterable) 求序列iterable中的TopN | nsmallest(n,iterable) 求序列iterable中的BtmN
import heapq
nums=[16,7,3,20,17,8,-1]
print(heapq.nlargest(3,nums))
print(heapq.nsmallest(3,nums))
[20, 17, 16]
[-1, 3, 7]
- nlargest(n, iterable, key=lambda) | nsmallest(n, iterable, key=lambda) key接受关键字参数,用于更复杂的数据结构中
def print_price(dirt):
for i in dirt:
for x,y in i.items():
if x=='price':
print(x,y)
portfolio = [
{'name': 'IBM', 'shares': 100, 'price': 91.1},
{'name': 'AAPL', 'shares': 50, 'price': 543.22},
{'name': 'FB', 'shares': 200, 'price': 21.09},
{'name': 'HPQ', 'shares': 35, 'price': 31.75},
{'name': 'YHOO', 'shares': 45, 'price': 16.35},
{'name': 'ACME', 'shares': 75, 'price': 115.65}
]
cheap=heapq.nsmallest(3,portfolio,key=lambda x:x['price'])
expensive=heapq.nlargest(3,portfolio,key=lambda y:y['price'])
print_price(cheap)
print_price(expensive)
price 16.35
price 21.09
price 31.75
price 543.22
price 115.65
price 91.1
sorted( )详解
- sorted(iterable, key=None, reverse=False)
- reverse=True 逆序
nums=[16,7,3,20,17,8,-1]
print(sorted(nums))
print(sorted(nums,reverse=True))
[-1, 3, 7, 8, 16, 17, 20]
[20, 17, 16, 8, 7, 3, -1]
str=['b','a','A','s']
print(sorted(str))
print(sorted(str,reverse=True))
['A', 'a', 'b', 's']
['s', 'b', 'a', 'A']
- key接受一个函数,且是个只接受一个元素的函数
- 多条件的key应该怎么写?
//按长度排序
L = [{1:5,3:4},{1:3,6:3},{1:1,2:4,5:6},{1:9}]
print(sorted(L,key=lambda x: len(x)))
[{1: 9}, {1: 5, 3: 4}, {1: 3, 6: 3}, {1: 1, 2: 4, 5: 6}]
//根据指定的值来排序(例如字典中的某个key)
L = [
('john', 'A', 15),
('jane', 'B', 10),
('dave', 'B', 12),
]
print(sorted(L,key=lambda x:x[2],reverse=True))
[('john', 'A', 15), ('dave', 'B', 12), ('jane', 'B', 10)]
portfolio = [
{'name': 'IBM', 'shares': 100, 'price': 91.1},
{'name': 'AAPL', 'shares': 50, 'price': 543.22},
{'name': 'FB', 'shares': 200, 'price': 21.09},
{'name': 'HPQ', 'shares': 35, 'price': 31.75},
{'name': 'YHOO', 'shares': 45, 'price': 16.35},
{'name': 'ACME', 'shares': 75, 'price': 115.65}
]
print(sorted(portfolio,key=lambda x:x['price']))
[{'shares': 45, 'name': 'YHOO', 'price': 16.35}, {'shares': 200, 'name': 'FB', 'price': 21.09}, {'shares': 35, 'name': 'HPQ', 'price': 31.75}, {'shares': 100, 'name': 'IBM', 'price': 91.1}, {'shares': 75, 'name': 'ACME', 'price': 115.65}, {'shares': 50, 'name': 'AAPL', 'price': 543.22}]
//不规则字符串,按“小写-大写-奇数-偶数”顺序排序
s = 'asdf234GDSdsf23'
print("".join(sorted(s, key=lambda x: (x.isdigit(),x.isdigit() and int(x) % 2 == 0,x.isupper(),x))))
addffssDGS33224
//一道面试题:要求:正数在前负数在后 2.整数从小到大 3.负数从大到小
list1=[7, -8, 5, 4, 0, -2, -5]
print(sorted(list1,key=lambda x:(x<0,abs(x))))
[0, 4, 5, 7, -2, -5, -8]
- 用operator中的函数加快速度和进行多级排序
from operator import itemgetter, attrgetter
暂不讨论
比较三种方法的效率
- 只求TopN=1/BtmN=1时,比较max( )和nlargest( )两种效率
In [8]: nums=random.sample(range(1,10000),999)
In [9]: print(max(nums))
9999
In [10]: %time
CPU times: user 0 ns, sys: 0 ns, total: 0 ns
Wall time: 13.1 µs
In [11]: heapq.nlargest(1,nums)
Out[11]: [9999]
In [12]: %time
CPU times: user 0 ns, sys: 0 ns, total: 0 ns
Wall time: 14.1 µs
- 当K为10,N为9(即N无限接近K时),比较了sorted( )+切片和nlargest( )两种方法的效率
In [23]: nums=random.sample(range(1,10000),10)
In [24]: sorted(nums,reverse=True)[:9]
Out[24]: [8814, 7551, 7318, 5597, 5257, 4437, 4211, 2776, 2440]
In [25]: %time
CPU times: user 0 ns, sys: 0 ns, total: 0 ns
Wall time: 11.4 µs
In [26]: heapq.nlargest(9,nums)
Out[26]: [8814, 7551, 7318, 5597, 5257, 4437, 4211, 2776, 2440]
In [27]: %time
CPU times: user 0 ns, sys: 0 ns, total: 0 ns
Wall time: 154 µs
- 当N较小时,比较了nlargest( )和sorted( )+切片两种方法
In [18]: nums=[16,7,3,20,17,8,-1]
In [19]: heapq.nlargest(3,nums)
Out[19]: [20, 17, 16]
In [20]: %time
CPU times: user 0 ns, sys: 0 ns, total: 0 ns
Wall time: 4.05 µs
In [21]: sorted(nums,reverse=True)[:3]
Out[21]: [20, 17, 16]
In [22]: %time
CPU times: user 0 ns, sys: 0 ns, total: 0 ns
Wall time: 5.48 µs
以上代码用到的import和show_tree( )
import math
import io
from io import StringIO
import heapq
import random
import time
from functools import wraps
def show_tree(tree, total_width=36, fill=' '):
output =io.StringIO() #创建stringio对象
last_row = -1
for i, n in enumerate(tree): #
if i:
row = int(math.floor(math.log(i+1, 2)))
else:
row = 0
if row != last_row:
output.write('\n')
columns = 2**row
col_width = int(math.floor((total_width * 1.0) / columns))
output.write(str(n).center(col_width, fill))
last_row = row
print(output.getvalue())
print('-' * total_width)
print(' ')
return参考资料
python3-cookbook-1.4-查找最大或最小元素
详解Python中heapq模块的用法(这里有实现show_tree的函数代码)
理解堆和堆排序的文章1
理解堆和堆排序的文章2
理解堆和堆排序的文章3
python奇技淫巧——max/min函数的用法
[PY3]——求TopN/BtmN 和 排序问题的解决的更多相关文章
- @NamedEntityGraphs --JPA按实体类对象参数中的字段排序问题得解决方法
JPA按实体类对象参数中的字段排序问题得解决方法@Entity @Table(name="complaints") @NamedEntityGraphs({ @NamedEntit ...
- 第2节 网站点击流项目(下):3、流量统计分析,分组求topN
四. 模块开发----统计分析 select * from ods_weblog_detail limit 2;+--------------------------+---------------- ...
- js关于对象键值为数字型时输出的对象自动排序问题的解决方法
一.对象键值为数字型时输出的对象自动排序问题如: var objs = { "1603":{id:"1603"}, "1702" ...
- Hadoop学习之路(二十)MapReduce求TopN
前言 在Hadoop中,排序是MapReduce的灵魂,MapTask和ReduceTask均会对数据按Key排序,这个操作是MR框架的默认行为,不管你的业务逻辑上是否需要这一操作. 技术点 MapR ...
- [LeetCode]LRU Cache有个问题,求大神解答【已解决】
题目: Design and implement a data structure for Least Recently Used (LRU) cache. It should support the ...
- hive求TopN语句
ROW_NUMBER,RANK(),DENSE_RANK() 先了解这三个之间的区别: Rank():1,2,2,4,5(一般用这个较多,不会影响总排名) Dense_rank():1,2,2,3,4 ...
- sicily 1046. Plane Spotting(排序求topN)
DescriptionCraig is fond of planes. Making photographs of planes forms a major part of his daily lif ...
- SQL分组求每组最大值问题的解决方法收集 (转载)
例如有一个表student,其结构如下: id name sort score 1 张三 语文 82 2 李四 数 ...
- 生成ansible-playbook的yaml文件的代码(字典排序问题无法解决)
import yaml import collections def add_task(): return None def add_vars(): return None def add_handl ...
随机推荐
- Backup--完整备份会打破现有的日志备份链么?
--问题描述: --对数据库有一个周期性数据库备份和事务日志备份的维护计划,在维护计划外有工作人员对数据库进行完整备份,该备份会打乱现有的日志备份链么? --===================== ...
- css 三彩loading
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title&g ...
- centos6.5安装配置网络
很多时候,Centos系统都是使用命令来管理的,如果当时安装系统时没有设置IP地址的话,那就只能在命令行设置了.当然对于高手来说,easy!但对于小白来说,头都大了,呵呵!下面简单说下我的操作吧 首先 ...
- 贝塞尔曲线 WPF MVVM N阶实现 公式详解+源代码下载
源代码下载 效果图: 本程序主要实现: N阶贝塞尔曲线(通用公式) 本程序主要使用技术 MVVM InterAction 事件绑定 动态添加Canvas的Item 第一部分公式: n=有效坐标点数量 ...
- leecode刷题(8)-- 两数之和
leecode刷题(8)-- 两数之和 两数之和 描述: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输 ...
- mysqldump导出数据不带时区信息的问题
今天在导出数据时,发现所有timestamp字段都不带时区信息,因为我在东8区,导出的数据中所有时间都提早了8个小时 首先先看表的字段和数据 CREATE TABLE IF NOT EXISTS `a ...
- linux设置ip别名
修改文件 # vi /etc/hosts 添加地址和别名 192.168.222.126 s1 ##前面是机器ip,后面是别名 测试 [root@bogon /]# ping s1 PING s1 ( ...
- Vim查找与替换
\c 忽略大小写 \C 强制区分大小写 \v 除了_.字母.数字以为的所有字符都当做具有特殊含义的字符 \V 只有反斜杠有特殊含义 %s///gn 统计某个词出现的次数 替换的flag g 全局范围执 ...
- 2018年10月19 手记 - 身为开发者的我de窘境
从10月1国庆过完节回来,那已经是7号了,之后便开始紧锣密鼓的筹划着接下来11月份的公司组织的对外活动,这边新来的产品对产品或者说对任务很是负责,并且策划了很多的方案,并且乐意站在我们开发的角度上去考 ...
- 海思3519A 移植 Qt 5.5.1
源码下载 网址:qt-everywhere-opensource-src-5.5.1.tar.gz 配置生成MakeFile 文件 解压源码包,在源码包路径下生成配置 MakeFile : ./con ...