@[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知道表示數字的符號的數值。