@[TOC](这里写目录标题
Python比较任何类型的序列时,会一一比较序列里的各个元素。
对字符串来说,比较的是码位。
对于非ASCII字符比较时, 非ASCII文本的标准排序方式是使用locale.strxfrm函数。
使用locale.strxfrm函数之前,必须先为应用设定合适的区域设置
>>> import locale
>>> locale.setlocale(locale.LC_COLLATE, 'pt_BR.UTF-8')
'pt_BR.UTF-8'
>>> fruits = ['caju', 'atemoia', 'cajá', 'açaí', 'acerola']
>>> sorted_fruits = sorted(fruits, key=locale.strxfrm)
>>> sorted_fruits
['açaí', 'acerola', 'atemoia', 'cajá', 'caju']
其中有几点要注意
- 区域设置是全局的,因此不推荐在库中调用setlocale函数
- 操作系统必须支持区域设置,否则setlocale函数会抛出locale.Error: unsupported locale setting异常。
- 必须知道如何拼写区域名称。
- 操作系统的制作者必须正确实现了所设的区域。
使用Unicode排序算法排序
James Tauber 开发了PyUCA库,这是Unicode排序算法(Unicode Collation Algorithm,UCA)的纯Python实现。
#使用pyuca.Collator.sort_key方法
>>> import pyuca
>>> coll = pyuca.Collator()
>>> fruits = ['caju', 'atemoia', 'cajá', 'açaí', 'acerola']
>>> sorted_fruits = sorted(fruits, key=coll.sort_key)
>>> sorted_fruits
['açaí', 'acerola', 'atemoia', 'cajá', 'caju']
Unicode数据库
Unicode标准提供了一个完整的数据库(许多格式化的文本文件),不仅包括码位与字符
名称之间的映射,还有各个字符的元数据,以及字符之间的关系。
unicodedata模块中有几个函数用于获取字符的元数据。
#Unicode数据库中数值字符的元数据示例(各个标号说明输出中的各列)
import unicodedata
import re
re_digit = re.compile(r'\d')
sample = '1\xbc\xb2\u0969\u136b\u216b\u2466\u2480\u3285'
for char in sample:
print('U+%04x' % ord(char), ➊
char.center(6), ➋
're_dig' if re_digit.match(char) else '-', ➌
'isdig' if char.isdigit() else '-', ➍
'isnum' if char.isnumeric() else '-', ➎
format(unicodedata.numeric(char), '5.2f'), ➏
unicodedata.name(char), ➐
sep='\t')
➊ U+0000格式的码位。
➋ 在长度为6的字符串中居中显示字符。
➌ 如果字符匹配正则表达式r’\d’,显示re_dig。
➍ 如果char.isdigit()返回True,显示isdig。
➎ 如果char.isnumeric()返回True,显示isnum。
➏ 使用长度为5、小数点后保留2位的浮点数显示数值。
➐ Unicode标准中字符的名称。
输出
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=
分析:第6列是在字符上调用unicodedata.numeric(char)函数得到的结果。这表明,Unicode知道表示数字的符号的数值。