设为首页 收藏本站
查看: 670|回复: 0

[经验分享] python 排序之Schwartzian转换

[复制链接]

尚未签到

发表于 2017-4-27 06:39:09 | 显示全部楼层 |阅读模式
  一、pthone 排序
  1、[].sort 排序:
  在Python里,可以使用`[].sort`实现默认的自然排序,其效率还不错。
  2、自定义函数排序:
  列表排序的顺序只是适用自然顺序,很多时候,你需要特定的顺序。比如需要排序的字段不是第一个字符,按照默认排序是毫无意义的。通过定义一个自定义函数返回-1则表示前者排在后者之前,返回0则表示二者顺序相同,返回1则表示后者排在前者之前,可以实现自己排序规则。 `cmp()`就是`[].sort()`的默认比较函数(在速度上'lst.sort()'远远超过'lst.sort(cmp)')。对于不太长的列表使用自定义比较函数可以快速的解决问题。
  在很多情况下,甚至可以直接使用一个'lambda'表达式来完成任务。 说到速度,使用自定义比较函数效率会很低。部分原因是Python的函数调用开销,函数本身也会增加花费的时间。不过有一种技术“Schwartzian转换”可以加速这种自定义排序。
  二、Schwartzian转换原理:
  Schwartzian转换是兰德尔施瓦兹在Perl中最先开始使用的,但其中的技巧同样适用于Python。 使用Schwartzian转换主要包括三个步骤,(准确的来说这是Guttman-Rosler转换(GRT),同样基于Schwartzian转换)


  •  将列表转换为可以用默认排序的列表。
  •  使用`[].sort()`排序。
  •  转回原先的格式。
  核心是将需要排序的对象转为一个能进行自然排序的字符串,任务里排序时间是主要因素的话,使用这项技术将大大提高效率(唯一的限制就是转换花费的时间不会很多)
  三、实例:
  考虑一个真实的案例:
  我们的网站每个关键页面的访问都会有Cookie Log进行记录,Cookie log记录了用户的真实IP,访问的URL,时间等用户访问信息,每个应用是通过vip技术负载均衡到后面的具体的应用里面,Cookie log是通过Apache的module进行记录,由于并发,日志写入是并不是有序的,我们现在需要安装访问时间排序,以方便分析日志。真实的一行记录如下:

46.72.70.123 - - - [12/Sep/2012:23:59:50 -0700] "GET /www.xxx.com tm?productId=593651545&rnd=134 5370HTTP/1.1" 200 2131 82269 "http://www.xxx.com/ite545.html" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1" - - "a=mt=1|ms=|mid=ru1012642554; b=W_signed=Y; c=-"–
  为了简单我们只取出时间不分排序,假设文本文件如下格式:

12/Sep/2012:23:59:50
12/Sep/2012:23:59:50
  考虑可以将12/Sep/2012:23:59:50 转换为 20120912235950 然后按照自然排序就好了。
  代码如下:

import sys, string, time, datetime   
wrerr = sys.stderr.write        
def get_Time(str):
print len(str)
print str
time = datetime.datetime.strptime(str,'%d/%b/%Y:%H:%M:%S')
return time.strftime("%Y%m%d%H%M%S")
lines = open(sys.argv[1]).readlines()        
start = time.time()      
for n in range(len(lines)):              
lst = string.split(lines[n])         
lines[n] = (get_Time(lines[n][:20]), lines[n])        
lines.sort()                          
for n in range(len(lines)):              
lines[n] = lines[n][1]        
end = time.time()
wrerr("Schwartzian transform sort in %3.2f secs\n" % (end-start))      
open('time.schwartzian','w').writelines(lines)
  核心在于get_Time函数,讲时间转换为可以自然排序的字符串。。
  上面真实的场景无非是在该函数的前面先将时间字符串获取,这个想必不难吧。。
  参考
  http://perl.plover.com/TPC/1998/Hardware-notes.html#Schwartzian_Transform
  http://docs.python.org/2/faq/programming.html#i-want-to-do-a-complicated-sort-can-you-do-a-schwartzian-transform-in-python
  本站支持 pay for your wishes

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-369647-1-1.html 上篇帖子: Python MySQLdb 学习总结 转 下篇帖子: Python学习——输入输出
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

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