如何按字符串长度和字母表顺序相反的方式对列表进行排序?

91

给定一个单词列表,返回一个按长度排序的单词列表(从长到短),第二排序标准应该是字母顺序。提示:你需要考虑两个函数。

到目前为止,这是我所拥有的内容:

def bylength(word1,word2):
    return len(word2)-len(word1)

def sortlist(a):
    a.sort(cmp=bylength)
    return a

它按长度排序,但我不知道如何将第二标准应用于此排序,该标准是按字母降序排列。

6个回答

188

你可以按照以下两个步骤完成:

the_list.sort() # sorts normally by alphabetical order
the_list.sort(key=len, reverse=True) # sorts by descending length

Python的sort方法是稳定的,这意味着按长度对列表排序时,当长度相等时,元素将按字母顺序排列。

你也可以像这样做:

the_list.sort(key=lambda item: (-len(item), item))

通常你不需要使用cmp,它甚至在Python3中已被删除。key更容易使用。


5
Lambda解决方案真是太棒了! - dmeu
第二个解决方案有点艺术化,我不知道关键字是这样工作的! - Masked Man
1
@jochen 当我这样做时,我会得到一个“'str' object has no attribute 'sort'”错误,因为我没有使用列表。它是从打开csv文件得到的字符串。有什么建议吗? - Edison
@Edison 这是一个老问题,但是你可以根据逗号/换行符进行分割来创建一个列表,然后应用这个解决方案。 - samm82
只是好奇为什么你在lambda函数中返回一个元组,而不是只返回-len(item) - Anthony Awuley

7
n = ['aaa', 'bbb', 'ccc', 'dddd', 'dddl', 'yyyyy']

for i in reversed(sorted(n, key=len)):
    print i

yyyyy dddl dddd ccc bbb aaa

for i in sorted(n, key=len, reverse=True):
     print i

yyyyy dddd dddl aaa bbb ccc


只有在数组已经排序的情况下才能正常工作。只有 sorted( sorted( iterable ), key=len ) 能始终给出正确的答案。 - user
@user 我刚刚尝试了未排序的数组。得到了相同(正确)的结果。你能提供一下你的输入数组吗? - Arindam Roychowdhury
sorted( ['bb', 'b', 'aa', 'a'], key=len, reverse=True) produces ['bb', 'aa', 'b', 'a'], but it should be ['aa', 'bb', 'a', 'b'] as get from sorted( sorted( ['bb', 'b', 'aa', 'a'] ), key=len, reverse=True) - user
这只是按字符串长度降序排序。 - frederick99

3
-Sort your list by alpha order, then by length.

See the following exmple:

>>> coursesList = ["chemistry","physics","mathematics","art"]
>>> sorted(coursesList,key=len)
['art', 'physics', 'chemistry', 'mathematics']
>>> coursesList.append("mopsosa")
>>> sorted(coursesList,key=len)
['art', 'physics', 'mopsosa', 'chemistry', 'mathematics']
>>> coursesList.sort()
>>> sorted(coursesList,key=len)
['art', 'mopsosa', 'physics', 'chemistry', 'mathematics']

2

首先按字母顺序排序,然后按长度排序。

这是一个可行的例子。

mylist.sort()
mylist = sorted(mylist, key=len, reverse=False)

# Print the items on individual line
for i in mylist:
    print(i)

-1

尽管Jochen Ritzel说你不需要cmp,但实际上,这是一个很好的运用场景!使用cmp,您可以同时按长度和字母顺序排序,只需要排序两次所需时间的一半!

def cmp_func(a, b):
    # sort by length and then alphabetically in lowercase
    if len(a) == len(b):
        return cmp(a, b)
    return cmp(len(a), len(b))

sorted_the_way_you_want = sorted(the_list, cmp=cmp_func)

例子:

>>> the_list = ['B', 'BB', 'AA', 'A', 'Z', 'C', 'D']
>>> sorted(the_list, cmp=cmp_func)
['A', 'B', 'C', 'D', 'Z', 'AA', 'BB']

请注意,如果您的列表是大小写混合的,请将 cmp(a, b) 替换为 cmp(a.lower(), b.lower()) 因为 Python 按字典序排序时 'a' > 'Z'

在 Python3 中,您需要使用定义了 __lt__ 样式比较函数或 functools.cmp_to_key() 自动为您完成此操作。 来对对象进行排序。


并不是非常有趣,因为cmp在Python 3中已经不存在了(正如你自己所说)。 - Jean-François Fabre

-2
def cmp_func(a, b):
    # sort by length and then alphabetically in lowercase
    if len(a) == len(b):
        return cmp(a, b)
    return cmp(len(a), len(b))

sorted_the_way_you_want = sorted(the_list, cmp=cmp_func)

你需要用 ``` 包围你的代码或在代码前面添加4个空格来放置它在代码块中。 - ljmc
1
目前你的回答不够清晰,请编辑并添加更多细节,以帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何编写好答案的更多信息。 - ljmc
“仅代码答案不是高质量的答案”(//meta.stackoverflow.com/questions/392712/explaining-entirely-code-based-answers)。虽然这些代码可能有用,但您可以通过解释它为什么有效、如何有效、何时应使用以及其限制等方面进行改进。请添加解释并链接相关文档,[编辑]您的回答。 - Stephen Ostermiller

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