Python 使用区域设置/排序规则按键对字典排序

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

下面的代码忽略了区域设置,最后是É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(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'))))