Guy
Guy

Reputation: 39

Sorting list by alphabetical order, with special case for certain starting letter

Given a list of strings, I want to return a list with the strings in sorted order, except group all the strings that begin with 'x' first.

For example:

['mix', 'xyz', 'apple', 'xanadu', 'aardvark']

Should yield:

['xanadu', 'xyz', 'aardvark', 'apple', 'mix']

I know it can be done by making 2 lists and sorting each of them before combining them, but I'm not sure how to write the condition in which 'x' is the first character.

Upvotes: 3

Views: 7259

Answers (5)

Stefan Pochmann
Stefan Pochmann

Reputation: 28636

>>> sorted(['mix', 'xyz', 'apple', 'xanadu', 'aardvark'],
           key=lambda x: (not x.startswith('x'), x))
['xanadu', 'xyz', 'aardvark', 'apple', 'mix']

The sorted() builtin returns a new, stable-sorted list() of each element in the input iterable, sorted by key. key, in this case, is a lambda expression (basically a "mini-function") which transforms or converts each element in the input list into a sortable value.

In this case, our lambda expression sorts each word in the list by a tuple() which contains False or True indicating whether or not the word starts with "x", followed by the word itself. Since False is "smaller" than True, the words that start with "x" appear first, and everything else is sorted alphabetically.

Upvotes: 1

Jean-François Fabre
Jean-François Fabre

Reputation: 140276

Just make a particular case in your key method: if starts with x, return a truncated string starting with "0" so it will appear first, but will be still sorted after "x".

z=['mix', 'xyz', 'apple', 'xanadu', 'aardvark']

z.sort(key=lambda x : "0"+x if x.startswith("x") else x)
print(z)

yields:

['xanadu', 'xyz', 'aardvark', 'apple', 'mix']

Upvotes: 2

miindlek
miindlek

Reputation: 3563

words = ['mix', 'xyz', 'apple', 'xanadu', 'aardvark']
result = [i for _, i in sorted((word[0]!='x', word) for word in words)]

Upvotes: 2

akhilmd
akhilmd

Reputation: 182

You can sort it using the built-in list.sort() and then use list comprehension to get the output you desire as follows:

sl = ['mix', 'xyz', 'apple', 'xanadu', 'aardvark']
sl.sort()
sl = [el for el in sl if el.startswith("x")]+[el for el in sl if not el.startswith("x")]

Upvotes: 0

falsetru
falsetru

Reputation: 369334

sorted or list.sort accepts optional key keyword argument. That is the function used to get sort key, and the return value of the function is used to compare instead of the original items.

>>> words = ['mix', 'xyz', 'apple', 'xanadu', 'aardvark']
>>> sorted(words, key=lambda word: (word[0] != 'x', word))
['xanadu', 'xyz', 'aardvark', 'apple', 'mix']

used word[0] != 'x'; which return False (0) for word starts with x, True (1) for other words; resulting words start with x come first.

Upvotes: 9

Related Questions