当前位置: 首页 > news >正文

Python Cookbook-5.2 不区分大小写对字符串列表排序

任务

你想对一个字符串列表排序,并忽略掉大小写信息。举个例子,你想要小写的a排在大写的 B 前面。默认的情况下,字符串比较是大小写敏感的(比如所有的大写字符排在小写字符之前)。

解决方案

采用 decorate-sort-undecorate(DSU)用法既快又简单:

def case_insensitive_sort(string_list):
	auxiliary_list = [(x.lower(),x) for x in string_list]	#decorate
	auxiliary_list.sort()									#sort
	return [x[1] for x in auxiliary_list]					#undecorate

Python 2.4已经提供对 DSU的原生支持了,因此(假设 string_list 的元素都是真正的普通字符串,而不是 Unicode 对象之类),可以用更简短更快的方式:

def case_insensitive_sort(string_list):
	return sorted(string_list,key=str.lower)

讨论

一个很明显的可选方案是编写一个比较函数,并将其传递给sort方法:

def case_insensitive_sort_1(string_list):
	def compare(a,b):return cmp(a.lower(),b.lower())
	string_list.sort(compare)

不过,在每次比较中,lower方法都会被调用两次,而对于长度为n的列表来说,比较的次数与 nlog(n)成正比。

DSU 方法则创建了一个辅助的列表,每个元素都是元组,元组的元素则来自原列表并被当做“键”处理。这个排序是基于键的,因为Python 的元组的比较是根据条目顺序进行的(比如,它会首先比较元组的第一个元素)。要将一个长度为n的字符串列表排序,配合 DSU的使用,lower方法只需要被调用n次,因而在第一步,decorate 阶段,以及最后一步,undecorate阶段节省了很多时间。

DSU 有时也被称为——但这种叫法不是很准确——Schwartzian变换,这是对Perl的一个著名应用的一个不太准确的类比。(如果要说相似,DSU 更接近于 Guttman-Rosler 变换,见http://www.sysarch.com/perl/sort_paper.html。)

DSU 是如此重要,因此 Python 2.4提供了对它的直接支持。可以给列表的 sort 方法传递一个可选的命名参数key,而且它可以被调用,作用于列表中的每个元素并获得用于排序的键。如果传递这样的一个参数,排序会在内部使用DSU。因此,在Python 2.4中string_list.sort(key=str.lower 实际上等价于 case_insensitive_sort 函数,只不过 sort 方法会直接作用于原列表(且返回 None),而不是返回一个排序完毕的拷贝且不对原列表做任何修改。如果你希望caseinsensitive sort 函数也能够直接作用于原列表,只需要将retumn 语句修改为对列表本体的赋值:

string_list{:] = [x[1] for x in auxiliary_list]

反过来,在 Python 2.4中,如果你希望获得一个排序完毕的拷贝,且让原列表保持不变
可以使用新的内建的 sorted 函数。比如,在Python2.4中:

for s in sorted(string_list,key = str.lower):print s

上述代码打印列表中的每一个字符串,这些字符串根据大小写无关的规则进行排序而且不会影响到 string_list 本身。

在 Python 2.4 的解决方案中,将 str.lower 作为 key 参数限制了你以特定的方式将字符串排序(不包括 Unicode 对象)。如果你知道你正在排序的是 Unicode 对象列表,可以使用 key=unicode.lower。如果你希望函数能够同时适用于普通字符串和 Unicode 对象,可以import string 并使用 key= string.lower;另外,也可以使用 key = lambda s: s.lower( )。

如果需要对字符串列表进行大小写无关的排序,可能也需要用大小写无关的字符串作为键的字典和集合,需要列表对 index 和 coumt 方法表现出与大小写无关的行为方式,需要在各种搜索匹配的任务中忽略掉大小写,等等。如果这是你的需求,那么真正需要的是 s的一个子类型,从而在比较和哈希的时候忽略大小写——相比于实现各种容器和函数来满足这些需求,这是解决这类问题的最好的方法。参考 1.24 节内容,可以看到如何实现这样一种子类型。

http://www.dtcms.com/a/109655.html

相关文章:

  • flux文生图部署笔记
  • unet结构, 为什么要下采样, 上采样?
  • Docker安装开源项目x-ui详细图文教程
  • 【一步步开发AI运动APP】六、运动计时计数能调用
  • 天津大学合成生物技术全国重点实验室-随笔09
  • USB(通用串行总线)数据传输机制和包结构简介
  • 【蓝桥杯】算法笔记2
  • 怎么让一台云IPPBX实现多家酒店相同分机号码一起使用
  • LJF-Framework 第13章 LjfAsyncManager异步任务管理
  • keep-alive缓存
  • [dp5_多状态dp] 按摩师 | 打家劫舍 II | 删除并获得点数 | 粉刷房子
  • HTTP数据传输的几个关键字Header
  • 《操作系统真象还原》第五章(1)——获取内存容量
  • Leetcode 1262 -- 动态规划
  • #window系统php-v提示错误#
  • 一周学会Pandas2 Python数据处理与分析-Pandas2简介
  • Node.js 与 MySQL:深入理解与高效实践
  • VisMin:视觉最小变化理解
  • 强化学习_Paper_1988_Learning to predict by the methods of temporal differences
  • 【Pandas】pandas DataFrame values
  • MacOS中配置完环境变量后执行source ~/.bash_profile后,只能在当前shell窗口中生效
  • 【eNSP实验】RIP协议
  • WHAT - JWT(JSON Web Token)
  • 颜色归一化操作
  • 设计心得——状态机
  • STM32单片机入门学习——第12节: [5-2]对射式红外传感器计次旋转编码器计次
  • 多模态学习(八):2022 TPAMI——U2Fusion: A Unified Unsupervised Image Fusion Network
  • MySQL数据库脱敏实战指南:从原理到企业级实现
  • torch.nn中的非线性激活介绍合集——Pytorch中的非线性激活
  • Webacy 利用 Walrus 技术构建链上风险分析决策层