【问题标题】:Sort list of tuples considering locale (swedish ordering)考虑语言环境的元组排序列表(瑞典排序)
【发布时间】:2012-03-03 14:23:27
【问题描述】:

显然 PostgreSQL 8.4 和 Ubuntu 10.04 无法处理对瑞典字母表的 W 和 V 进行排序的更新方式。也就是说,它仍然像这样以相同的字母对它们进行排序(瑞典排序的旧定义):

  • Vb
  • 厕所
  • Vd

应该是(瑞典订购的新定义):

  • Vb
  • Vd
  • 厕所

我需要为我正在构建的 Python/Django 网站正确订购此产品。我尝试了各种方法来使用 *values_list* 对从 Django QuerySet 创建的元组列表进行排序。但由于它是瑞典语,因此 å、ä 和 ö 字母也需要正确排序。现在我有一种或另一种方式,两者都不是..

list_of_tuples = [(u'Wa', 1), (u'Vb',2), (u'Wc',3), (u'Vd',4), (u'Öa',5), (u'äa',6), (u'Åa',7)]

print '########## Ordering One ##############'
ordered_list_one = sorted(list_of_tuples, key=lambda t: tuple(t[0].lower()))
for item in ordered_list_one:
    print item[0]

print '########## Ordering Two ##############'
locale.setlocale(locale.LC_ALL, "sv_SE.utf8")
list_of_names = [u'Wa', u'Vb', u'Wc', u'Vd', u'Öa', u'äa', u'Åa']
ordered_list_two = sorted(list_of_names, cmp=locale.strcoll)
for item in ordered_list_two:
    print item

例子给出:

########## Ordering One ##############
Vb
Vd
Wa
Wc
äa
Åa
Öa
########## Ordering Two ##############
Wa
Vb
Wc
Vd
Åa
äa
Öa

现在,我想要的是这些的组合,以便 V/W 和 å,ä,ö 排序都是正确的。更准确地说。我希望 Ordering One 尊重语言环境。然后在每个元组中使用第二个项目(对象 ID),我可以在 Django 中获取正确的对象。

我开始怀疑这是否可行?是否可以将 PostgreSQL 升级到更好地处理排序规则然后在 Django 中使用原始 SQL 的新版本?

【问题讨论】:

  • 我认为 Postgres 8.4 和 Ubuntu 10.04 LTS 应该没问题。您的集群设置为什么语言环境?您可以通过命令“show lc_collat​​e;”来判断这一点
  • 我应该提到集群 (sv_SE) 的区域设置是正确的。我必须更早地更改此设置才能正确排序 å、ä 和 ö。

标签: python django postgresql locale


【解决方案1】:

在 Ubuntu-10.04 上的示例上运行 LC_ALL=sv_SE.UTF-8 sort 时,它在 Vb 之前出现 Wa(“旧方式”),因此 Ubuntu 似乎不同意“新方式”。 由于 PostgreSQL 为此依赖于操作系统,因此它的行为与给定相同 lc_collat​​e 的操作系统相同。

实际上在 debian glibc 中有一个补丁与这个特定的排序问题相关: http://sourceware.org/bugzilla/show_bug.cgi?id=9724 但遭到反对,不被接受。如果您只在您管理的系统上需要此行为,您仍然可以将补丁更改应用到 /usr/share/i18n/locales/sv_SE 并通过运行 locale-gen sv_SE.UTF-8 重建 se_SV 语言环境。或者更好的是,创建您自己的替代语言环境,以避免与原始语言发生冲突。

【讨论】:

  • 似乎我试图在我正在使用的堆栈的错误端解决问题。我完全控制了主机,所以使用该补丁没有问题。非常感谢!
【解决方案2】:

这个解决方案很复杂,因为 key=locale.strxfrm 工作正常 使用单个列表和字典,但不使用列表列表或 元组列表。

从 Py2 -> Py3 的变化:使用 locale.setlocale(locale.LC_ALL, '') 和 key='locale.strxfrm'(而不是 'cmp=locale.strcoll')。

list_of_tuples = [('Wa', 1), ('Vb',2), ('Wc',3), ('Vd',4), ('Öa',5), ('äa',6), ('Åa',7)]

def locTupSorter(uLot):
    "Locale-wise list of tuples sorter - works with most European languages"
    import locale
    locale.setlocale(locale.LC_ALL, '') # get current locale

    dicTups = dict(uLot)          # list of tups to unsorted dictionary
    ssList = sorted(dicTups, key=locale.strxfrm)
    sLot = []
    for i in range(len(ssList)):  # builds a sorted list of tups 
        tfLot = ()
        elem = ssList[i]          # creates tuples for list
        tfLot = (elem, dicTups[elem])
        sLot.append(tfLot)        # creates sorted list of tuples
    return(sLot)


print("list_of_tuples=\n", list_of_tuples)
sortedLot = locTupSorter(list_of_tuples)
print("sorted list of tuples=\n",sortedLot)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多