Python中按字典顺序对字符串进行排序

31
我想将一个字符串按字典顺序排序成列表,如下所示:
str='aAaBbcCdE'

为了

['A','a','a','B','b','C','c','d','E']

但是sorted()给我这个输出:
['A','B','C','E','a','a','b','c','d']

我该如何进行字典序排序?
6个回答

41

在有内置函数可以完成任务时,不要使用 lambda 函数。而且永远不要使用 sorted 的 cmp 参数,因为它已经被弃用了:

sorted(s, key=str.lower)
或者
sorted(s, key=str.upper)

但这种方法可能无法保证'A'和'a'的顺序,因此:

sorted(sorted(s), key=str.upper)

通过使用sorted函数,对于几乎有序的列表(第二个sorted),操作将非常快速。


sorted(sorted(s), key=str.upper) 突出。 - Abhijeet
1
自Python 3.3以来,str.casefold是比str.lower或str.upper更好的键函数,因为它返回适用于无大小写比较的字符串版本。 - samwyse

17

您可以使用一个二元组作为键:

text='aAaBbcCdE'
sorted(text, key=lambda x: (str.lower(x), x))
# ['A', 'a', 'a', 'B', 'b', 'C', 'c', 'd', 'E']

元组中的第一个元素 str.lower(x) 是主键(使得 aB 之前),而 x 本身则是用来解决冲突的(使得 Aa 之前)。


这对我解决了问题,但我不明白为什么返回 x 不会导致正确的排序,而返回 (lower(x), x) 则会。有人能解释一下吗? - Scott Gartner
1
@ScottGartner 返回一个二元组 (lower(x), x),基本上使用了元组的字典序排序:所有在元组索引0处相等的元素将按照索引1处的元素进行排序,所有在索引0处不同的元素将按照通常的方式进行排序。 - Raffi
这是目前为止最好的答案! - Raffi

4

cmp 是旧的做法,现在已经被弃用,但为了记录:

s='aAaBbcCdE'
sorted(s, lambda x,y: cmp(x.lower(), y.lower()) or cmp(x,y))

7
这是被废弃的排序方式,请使用 sorted。 - JBernardo
1
@KarolyHorvath,明显一点,修正你的答案,他就不必再纠正了。 - Russia Must Remove Putin
@AaronHall:这会使评论变得误导。不,谢谢。 - Karoly Horvath
2
实际上,让我们把这个答案留在这里 :D - Antti Haapala -- Слава Україні

0

data = input() data=list(data) data.sort()

现在变量“data”将拥有按词典顺序排序的输入。


0

如果你不是在处理一组简单字符串,而是想按自然排序顺序而不是字典排序顺序进行排序:

假设你有一组对象实例,你想按特定属性对它们进行排序,而属性值可以以大写或小写字母开头,那么你可以这样做:

sorted(objects, lambda object: object.attr1.lower())

假设attr1是字符串类型。为什么这样做有效呢?因为你将所有排序键转换为相同的大小写,以便进行排序,从而打败了词典排序。如果不使用lower()或upper(),则会导致词典排序顺序而不是自然字母顺序。

-1

使用natsort库。 最好使用库而不是stackoverflow上的代码解决方案。(在某个SO位置读到的)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接