92

Given a list of words, return a list with the same words in order of length (longest to shortest), the second sort criteria should be alphabetical. Hint: you need think of two functions.

This is what I have so far:

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

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

it sorts by length but I don't know how to apply the second criteria to this sort, which is by alphabetical descending.

0

6 Answers 6

194

You can do it in two steps like this:

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

Python's sort is stable, which means that sorting the list by length leaves the elements in alphabetical order when the length is equal.

You can also do it like this:

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

Generally you never need cmp, it was even removed in Python3. key is much easier to use.

5
  • 5
    the lambda solution is awe-some!
    – dmeu
    Commented Mar 18, 2016 at 16:31
  • The second solution was a bit of art and I didn't know key works that way!
    – Masked Man
    Commented Apr 30, 2019 at 15:45
  • 1
    @jochen When I do this I get an 'str' object has no attribute 'sort' error because I'm not using a list. It's a string from opening the csv. Any suggestions?
    – Edison
    Commented May 13, 2020 at 15:46
  • @Edison old question, but you could split at commas/line separators to create a list and then apply this solution
    – samm82
    Commented Dec 17, 2020 at 23:54
  • just wondering why you are returning a tuple in the lambda function when you could only return -len(item) Commented Mar 6, 2022 at 15:58
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

4
  • This only works if the array is already sorted. Only sorted( sorted( iterable ), key=len ) gives the correct answer always. Commented Jun 16, 2018 at 18:46
  • @user I just tried with unsorted array . Getting the same (correct) result . Can you please provide your input array ? Commented Jun 18, 2018 at 7:36
  • 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) Commented Jun 18, 2018 at 13:48
  • This is simply sorting by string length in descending order. Commented Sep 21, 2021 at 23:09
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

First sort by Alphabet and then sort by Length.

Here is a working example

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

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

Although Jochen Ritzel said you don't need cmp, this is actually a great use case for it! Using cmp you can sort by length and then alphabetically at the same time in half the time sorting twice would take!

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)

Example:

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

Note, if your list is a mix of upper and lower case replace cmp(a, b) with cmp(a.lower(), b.lower()) as python sorts 'a' > 'Z'.

In python3 you'd need to be sorting objects with __lt__ style comparison functions defined or functools.cmp_to_key() which does that for you.

1
  • not very interesting as cmp doesn't exist in python 3 anymore (you said it yourself) Commented Dec 4, 2018 at 21:04
-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)
3
  • You need to sourround your code with ``` or prepend 4 spaces to put it in code blocks.
    – ljmc
    Commented May 13, 2022 at 13:20
  • 1
    As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
    – ljmc
    Commented May 13, 2022 at 13:20
  • A code-only answer is not high quality. While this code may be useful, you can improve it by saying why it works, how it works, when it should be used, and what its limitations are. Please edit your answer to include explanation and link to relevant documentation. Commented Feb 9, 2023 at 10:29

Not the answer you're looking for? Browse other questions tagged or ask your own question.