I'm supposed to take a list of words and sort it, except I need to group all Strings that begin with 'x' first.
Here's what I got:
list_1 = []
list_2 = []
for word in words:
list_1.append(word) if word[0] == 'x' else list_2.append(word)
return sorted(list_1) + sorted(list_2)
But I have a feeling there is a much more elegant way to do this...
EDIT
Example:
['mix', 'xyz', 'apple', 'xanadu', 'aardvark']
yields ['xanadu', 'xyz', 'aardvark', 'apple', 'mix']
.
>>> words = ['xoo', 'dsd', 'xdd']
>>> sorted(words, key=lambda x: (x[0] != 'x', x))
['xdd', 'xoo', 'dsd']
Explanation: the key function returns a pair (tuple). The first element is False
or True
, depending on whether the first char in the string is 'x'
. False
sorts before True
, so strings starting with 'x'
will be first in the sorted output. The second element in the tuple will be used to compare two elements that are the same in the first element, so all the strings starting with 'x'
will be sorted amongst themselves, and all the strings not starting with 'x'
will be sorted amongst themselves.
First: stop saying "pythonic" when you mean "clean". It's just a cheesy buzzword.
Don't use terniary expressions like that; it's meant to be used as part of an expression, not as flow control. This is cleaner:
for word in words:
if word[0] == 'x':
list_1.append(word)
else:
list_2.append(word)
You can improve it a bit more--using terniary expressions like this is fine:
for word in words:
target = list_1 if word[0] == 'x' else list_2
target.append(word)
If words
is a container and not an iterator, you could use:
list_1 = [word for word in words if word[0] == 'x']
list_2 = [word for word in words if word[0] != 'x']
Finally, we can scrap the whole thing, and instead use two sorts:
result = sorted(words)
result = sorted(result, key=lambda word: word[0] != 'x')
which first sorts normally, then uses the stable property of Python sorts to move words beginning with "x" to the front without otherwise changing the ordering.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With