Python 使用区域设置/排序规则按键对字典排序
下面的代码忽略了区域设置,最后是Égypt,怎么了Python 使用区域设置/排序规则按键对字典排序,python,python-2.7,Python,Python 2.7,下面的代码忽略了区域设置,最后是Égypt,怎么了 dict = {"United States": "United States", "Spain" : "Spain", "England": "England", "Égypt": "Égypt"} import locale # using your default locale (user settings) locale.setlocale(locale.LC_ALL,"fr_FR") print OrderedDict(sorte
dict = {"United States": "United States", "Spain" : "Spain", "England": "England", "Égypt": "Égypt"}
import locale
# using your default locale (user settings)
locale.setlocale(locale.LC_ALL,"fr_FR")
print OrderedDict(sorted(dict.items(), key=lambda t: t[0], cmp=locale.strcoll))
这就是输出:
OrderedDict([('England', 'England'), ('Spain', 'Spain'), ('United States', 'United States'), ('\xc3\x89gypt', '\xc3\x89gypt')])
这里有一个解决办法
使用unicode的规范化形式规范化分解
#utf-8 unicode留给读者作为练习
埃及=unicodedata.正常化(“NFD”,埃及)
已排序(['Egypt','E\xcc\x81gypt','US'])
['Egypt','E\xcc\x81gypt','US']
这实际上并没有考虑语言环境
除此之外,请尝试更新的Python(是的,我知道)或来自Martijn的链接问题和相应答案的ICU库。考虑以下内容
import unicodedata
from collections import OrderedDict
dict = {"United States": "United States", "Spain" : "Spain", "England": "England", "Égypt": "Égypt"}
import locale
# using your default locale (user settings)
locale.setlocale(locale.LC_ALL,"fr_FR")
print OrderedDict(sorted(dict.items(),cmp= lambda a,b: locale.strcoll(unicodedata.normalize('NFD', unicode(a)[0]).encode('ASCII', 'ignore'),
unicodedata.normalize('NFD', unicode(b)[0]).encode('ASCII', 'ignore'))))
我认为你不能同时指定
键
和cmp
@Daniel实际上你可以。。。这样做很奇怪(key的结果最终被传递给cmp)这里最大的问题是不清楚locale
编码会尊重fr\u fr
。即使设置locale.setlocale(locale.LC_ALL,“fr\u fr.UTF-8”)
以匹配我的终端设置,埃及仍然排在最后。这与中描述的完全一样,如果我先解码为unicode,这并不重要。这是因为区域设置中的排序是跨平台的。因此,结论是这篇文章是一篇重复的文章,而其他提到PyICU的文章,因为这是这个问题的正确答案。确实必须有一个更好的解决方案,而不是仅仅为了更改区域设置而编写代码。还应该注意,设置区域设置可能会对python实例的其他部分产生影响。
import unicodedata
from collections import OrderedDict
dict = {"United States": "United States", "Spain" : "Spain", "England": "England", "Égypt": "Égypt"}
import locale
# using your default locale (user settings)
locale.setlocale(locale.LC_ALL,"fr_FR")
print OrderedDict(sorted(dict.items(),cmp= lambda a,b: locale.strcoll(unicodedata.normalize('NFD', unicode(a)[0]).encode('ASCII', 'ignore'),
unicodedata.normalize('NFD', unicode(b)[0]).encode('ASCII', 'ignore'))))