如何在Python中以不区分大小写和确定大小写的方式对文本字符串排序

2024-06-16 10:56:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我的标准要求是对文本字符串列表进行不区分大小写的排序。但是,另外,这种排序需要是确定性的,,因为包含相同元素的两个列表应该导致相同的排序列表

为了解释这个问题,请考虑以下两个列表:

l1 = ['alfred', 'Berta', 'berta', 'carl']
l2 = ['alfred', 'berta', 'carl', 'Berta']

显然,两个列表具有相同的元素:

>>> set(l1) == set(l2)
True

为了对这些列表进行排序,我在第一次尝试中使用了带有str.casefoldas key参数的builtin function ^{}函数。但这会导致两个不同的结果列表:

>>> sorted(l1, key=str.casefold)
['alfred', 'Berta', 'berta', 'carl']
>>> sorted(l2, key=str.casefold)
['alfred', 'berta', 'Berta', 'carl']

但是,在这两种情况下,我都需要相同的输出

['alfred', 'Berta', 'berta', 'carl']

我怎样才能做到这一点

我的方法的问题是key函数“吃掉了要排序的元素的一些信息”。那么,是否可以用一个特定的key函数来sorted实现这一点呢?此函数需要保留完整的大小写信息,但仍会在对应的小写字母旁边排序大写字母


奖金问题:

如何使此排序完全独立于区域设置,以便在使用不同国家/地区设置的机器上从相同文件读取列表时,最终列表始终以完全相同的方式排序


Tags: key函数元素l1列表排序sortedset
2条回答

您可以首先使用区分大小写的方法对它们进行排序,然后再次忽略大小写进行排序

>>> sorted(sorted(l1), key=str.casefold)
['alfred', 'Berta', 'berta', 'carl']
>>> sorted(sorted(l2), key=str.casefold)
['alfred', 'Berta', 'berta', 'carl']

我的看法:

def prepare_stable_sort(x):
    return (x.casefold(), id(x))

list(sorted(l1, key=prepare_stable_sort))
list(sorted(l2, key=prepare_stable_sort))

这将使用普通的casefold,但也添加哈希,以区分casefold给出相同结果的情况。注意:这仅在同一处理器上是稳定的。为了消除散列攻击,我认为现在散列是部分随机的

对于一个完整的解决方案,我将使用Unicode字符串比较(因此它适用于所有地区,但也是以一种合理的方式,尽管对于特定语言不是100%正确),并且我还将添加一个可复制的哈希函数

相关问题 更多 >