Unicode文本排序内置方法

python中提供了标准的排序方法但是在内置的方法可能带来一个不好的结果,尤其是比较非 ASCII 字符时。例如下面的例子.

由于不同的区域才去的排序规则不一样,下面的例子实际的排序是这样子的:
['açaí', 'acerola', 'atemoia', 'cajá', 'caju']
而现在的排序结果确实这样子的:
['acerola', 'atemoia', 'açaí', 'caju', 'cajá']

这是由于葡萄牙语等很多语言按照拉丁字母表排序,重音符号和下加符对排序几乎没什么影响.

在python中,非 ASCII 文本的标准排序方式是使用 locale.strxfrm 函数,把字符串转换成适合所在区域进行比较的形式,使用 locale.strxfrm 函数之前,必须先为应用设定合适的区域设置,这里还有一个条件是操作系统支持这项设置.

  • 但是区域设置是全局的,因此不推荐在库中调用 setlocale 函数.
  • 对于不同的操作系统,需要注意使用情况,有的系统不响应该操作.
fruits = ['caju', 'atemoia', 'cajá', 'açaí', 'acerola']
print(sorted(fruits))
['acerola', 'atemoia', 'açaí', 'caju', 'cajá']

使用Unicode排序算法排序

使用PyUCA 库来解决上面的烦恼,Unicode 排序算法(Unicode Collation
Algorithm,UCA)的纯 Python 实现。目前支持 Python 3.x版本.这里需要自己去下载,在windows下载路径.

PyUCA 没有考虑区域设置,如果想定制排序方式,可以把自定义的排序表路径传给
Collator() 构 造 方 法。

import pyuca
coll = pyuca.Collator()
fruits = ['caju', 'atemoia', 'cajá', 'açaí', 'acerola']
sorted_fruits = sorted(fruits,key=coll.sort_key)
print(sorted_fruits)

Unicode数据库

Unicode 标准提供了一个完整的数据库(许多格式化的文本文件),不仅包括码位与字符名称之间的映射,还有各个字符的元数据,以及字符之间的关系。

  • Unicode 数据库记录了字符是否可以打印 isprintable,
  • 是不是字母isdecimal,
  • 是不是数字 isnumeric,
  • 或者是不是其他数值符号 isidentifier
  • str.casefold 方法也用到了 Unicode 表中的信息:unicodedata.name()

如下案例

import unicodedata
import rere_digit = re.compile(r'\d')sample = '1\xbc\xb2\u0969\u136b\u216b\u2466\u2480\u3285' for char in sample:print('U+%04x' % ord(char),     # U+0000 格式的码位。char.center(6),           #在长度为 6 的字符串中居中显示字符're_dig' if re_digit.match(char) else '-', #如果字符匹配正则表达式 r'\d',显示 re_dig'isdig' if char.isdigit() else '-', #  如果 char.isdigit() 返回 True,显示 isdig'isnum' if char.isnumeric() else '-', #   如果 char.isnumeric() 返回 True,显示 isnumformat(unicodedata.numeric(char),'5.2f'), #  使用长度为 5、小数点后保留 2 位的浮点数显示数值unicodedata.name(char), #  Unicode 标准中字符的名称sep ='\t')
U+0031    1     re_dig  isdig   isnum    1.00   DIGIT ONE
U+00bc   ¼     -   -   isnum    0.25   VULGAR FRACTION ONE QUARTER
U+00b2   ²     -   isdig   isnum    2.00   SUPERSCRIPT TWO
U+0969   ३     re_dig  isdig   isnum    3.00   DEVANAGARI DIGIT THREE
U+136b   ፫     -   isdig   isnum    3.00   ETHIOPIC DIGIT THREE
U+216b   Ⅻ     -   -   isnum   12.00   ROMAN NUMERAL TWELVE
U+2466   ⑦     -   isdig   isnum    7.00   CIRCLED DIGIT SEVEN
U+2480   ⒀     -   -   isnum   13.00   PARENTHESIZED NUMBER THIRTEEN
U+3285   ㊅     -   -   isnum    6.00   CIRCLED IDEOGRAPH SIX

标准库中的一些函数能接受字符串或字节序列为参数,然后根据类型展现不同的行为

正则表达式中的字符串和字节序列

如果使用字节序列构建正则表达式,\d 和 \w 等模式只能匹配 ASCII 字符;相比之下,如果是字符串模式,就能匹配 ASCII 之外的 Unicode 数字或字。
可以使用正则表达式搜索字符串和字节序列,但是在后一种情况中,ASCII 范围外的字节不会当成数字和组成单词的字母母。

import re # 前两个正则表达式是字符串类型
re_numbers_str = re.compile(r'\d+')
re_words_str = re.compile(r'\w+')# 后两个正则表达式是字节序列类型
re_numbers_bytes = re.compile(rb'\d+')
re_words_bytes = re.compile(rb'\w+') # 要搜索的 Unicode 文本,包括 1729 的泰米尔数字
text_str = ("Ramanujan saw \u0be7\u0bed\u0be8\u0bef"" as 1729 = 1³ + 12³ = 9³ + 10³.") # 字节序列只能用字节序列正则表达式搜索
text_bytes = text_str.encode('utf_8')print('Text', repr(text_str), sep='\n  ')
print('Numbers')
# 字符串模式 r'\d+' 能匹配泰米尔数字和 ASCII 数字
print('  str  :', re_numbers_str.findall(text_str))
#字节序列模式 rb'\d+' 只能匹配 ASCII 字节中的数字
print('  bytes:', re_numbers_bytes.findall(text_bytes))
print('Words')
# 字符串模式 r'\w+' 能匹配字母、上标、泰米尔数字和 ASCII 数字
print('  str  :', re_words_str.findall(text_str))
#  字节序列模式 rb'\w+' 只能匹配 ASCII 字节中的字母和数字
print('  bytes:', re_words_bytes.findall(text_bytes))
Text'Ramanujan saw ௧௭௨௯ as 1729 = 1³ + 12³ = 9³ + 10³.'
Numbersstr  : ['௧௭௨௯', '1729', '1', '12', '9', '10']bytes: [b'1729', b'1', b'12', b'9', b'10']
Wordsstr  : ['Ramanujan', 'saw', '௧௭௨௯', 'as', '1729', '1³', '12³', '9³', '10³']bytes: [b'Ramanujan', b'saw', b'as', b'1729', b'1', b'12', b'9', b'10']

os函数中的字符串和字节序列

os 模 块 中 的 所 有 函 数、 文 件 名 或 路 径 名 参 数 既 能 使 用 字 符串,也能使用字节序列。如果这样的函数使用字符串参数调用,该参数会使用 sys.getfilesystemencoding() 得到的编解码器自动编码,然后操作系统会使用相同的编解码器解码。

  • fsencode(filename)

如果 filename 是 str 类型(此外还可能是 bytes 类型),使用 sys.getfilesystemencoding()
返回的编解码器把 filename 编码成字节序列;否则,返回未经修改的 filename 字节
序列。

  • fsdecode(filename)

如 果 filename 是 bytes 类 型( 此 外 还 可 能 是 str 类 型 ), 使 用 sys.getfilesystemen-
coding() 返回的编解码器把 filename 解码成字符串;否则,返回未经修改的 filename
字符串。


分享关于人工智能,机器学习,深度学习以及计算机视觉的好文章,同时自己对于这个领域学习心得笔记。想要一起深入学习人工智能的小伙伴一起结伴学习吧!扫码上车!

Python进阶14_Unicode排序相关推荐

  1. Python进阶6——序列操作

    1.序列的拼接和复制 Python中使用+对序列进行拼接,使用*对序列进行复制 s=str(1234) l=list(range(2,13)) print(s,l) print('---------- ...

  2. Python进阶(2)

    Python进阶(2) 题目来自于慕课网,python进阶课程 本系列笔记来自于慕课网的学习成果. 题目1 Python中自定义排序函数 Python内置的sorted()函数可对list进行排序: ...

  3. python进阶指南_Python特性工程动手指南

    python进阶指南 介绍 (Introduction) In this guide, I will walk through how to utilize data manipulating to ...

  4. python进阶20装饰器

    原创博客地址:python进阶20装饰器 Nested functions Python允许创建嵌套函数,这意味着我们可以在函数内声明函数并且所有的作用域和声明周期规则也同样适用. 1 2 3 4 5 ...

  5. 学习Python全套代码【超详细】Python入门、核心语法、数据结构、Python进阶【致那个想学好Python的你】

    大家早上好,本人姓吴,如果觉得文章写得还行的话也可以叫我吴老师.欢迎大家跟我一起走进数据分析的世界,一起学习! 感兴趣的朋友可以关注我的数据分析专栏,里面有许多优质的文章跟大家分享哦. 文末附上详细的 ...

  6. 7.1.3 Python进阶 《函数》定义、调用,参数,返回值《面向对象》概念,类,实例,对象,属性,方法《模块、包》导入,自定义,常用内置:datatime,time,random,os,sys

    目录 ======== 第四部分 Python进阶 ======== 第一节 函数 4.1.1 函数定义及调用 4.1.2 函数的参数 4.1.3 函数的返回值 第二节 面向对象 4.2.1 面向对象 ...

  7. python进阶数据分析_数据分析--Part 2: Python进阶

    笔记内容来源:拉勾教育数据分析实战训练营 本篇是Part 2,python的进阶部分开始啦~~~~~~~ 说明:理论部分是提炼的老师所讲,加上我自己看书添加的一些解释,代码部分有些会融合老师和我自己练 ...

  8. python输入数字并排序_「每日一练」巧用Python实现数字排序

    原标题:「每日一练」巧用Python实现数字排序 数字排序在我们的生产和生活中占着非常大的比重,这种思维和技术可以让一组数据更快更明了的展现在我们的面前,极大的提高了我们的工作效率! 那么,你知道如何 ...

  9. Python进阶----pymysql模块的使用,单表查询

    Python进阶----pymysql模块的使用,单表查询 一丶使用pymysql ​   ​   1.下载pymysql包: pip3 install pymysql ​​   ​   2.编写代码 ...

最新文章

  1. STL中heap算法(堆算法)
  2. 2020 年,Linux 设备或将爆炸式增长
  3. windows下,怎么轻易拷贝一个文件的完整路径?
  4. 启动DevStack的各项服务
  5. SAP Spartacus里cx-carousel的实现
  6. pythonstdin_如何在Python中执行将数据写入stdin的进程?
  7. 【多线程】线程的生命周期
  8. 上位机plc编程入门_上位机-使用C#编程语言编写PLC上位机软件-技术论坛-西门子中国...
  9. 空号检测(电话号码状态实时分析)freeswitch模块
  10. Vue使用iconfont图标
  11. 微信付款为什么无法连接服务器,前台微信付款报错:无法连接服务器,请检查网络连接?...
  12. HTML5实现3D校园地图思路
  13. 解决操作无法完成,因为其中的文件夹或文件已在另一程序中打开的问题
  14. 实用的 PyYAML 使用技巧
  15. ESP8266 SmartConfig一键配网
  16. Linux运维后台进程管理之Supervisor配置和常用命令常见问题案例和管理odoo后台进程
  17. 正则表达式 ^$ 同时出现代表什么
  18. 贺利坚的课程教学链接
  19. bootstrapt 表格自适应_好用的自适应表格插件-bootstrap table (支持固定表头)
  20. lottie android 源码,Lottie动画库 Android 端源码浅析

热门文章

  1. 如何修改默认调试器-windbg
  2. java计算机毕业设计vue图书管理系统源码+mysql数据库+系统+lw文档+部署
  3. 秒懂 栈内存和堆内存(深入底层)
  4. 基金公司官方网站设计建设
  5. Visual Studio中出现弹窗“未将对象引用设置到对象的实例”
  6. pythonchallenge闯关游戏_Python Challenge游戏攻略(一)
  7. cad抛物线曲线lisp_如何用CAD画正弦曲线????有lisp的最好。。。谢谢了
  8. android q启动前台服务,Android 启动前台服务,适配 vivo 与 OPPO 手机,第一期
  9. kill掉僵尸进程的方法(kill -9 <PPID>)
  10. java:3: 错误: 编码 GBK 的不可映射字符 (0x8E)