I have the following sorting problem:
Given a list of strings, return the list of strings sorted, but group all strings starting with 'x' first.
Example: ['mix', 'banana' ,'xyz', 'apple', 'xanadu', 'aardvark'] Will return: ['xanadu', 'xyz', 'aardvark', 'apple', 'banana' ,'mix']
I solved by splitting the list into 2:
def front_x(words):
return [w for w in words if w[0] == "x"] [w for w in words if w[0] != "x"]
Another pythonic solution for this problem would be using sorted
method, like this:
def front_x(words):
return sorted(words, key=lambda x: x if x[0] == 'x' else f'y{x}')
I am having a hard time to understand what is going on after else
. Any good soul to help me out? I'm grateful.
CodePudding user response:
f'y{x}'
in an f-string expression that prepends the character 'y'
to the original string (x
). That way, all items that don't start with 'x'
will sort as if they started with 'y'
, which puts them after all of the items that do start with 'x'
.
For example, 'banana'
will be sorted as if it was 'ybanana'
, which naturally places it after 'xyz'
.
CodePudding user response:
return sorted(words, key=lambda x: x if x[0] == 'x' else f'y{x}')
Translation:
"Return a sorted version of words
. For each item x
in words
, use x
for comparison when sorting, but only if x[0]
is equal to the character 'x'
. Otherwise, append 'y'
to the front of x
and use that for comparison instead"
The f'y{x}'
syntax is the f-string syntax. It's equivalent to:
"y" str(x)
There are plenty of other equivalent ways to insert a character into a string. That's just how it's being done here.
So, if your word list was:
aardvark
xylophone
xamarin
xenophobia
zipper
apple
bagel
yams
The list would be sorted as if it contained the following:
yaardvark
xylophone
xamarin
xenophobia
yzipper
yapple
ybagel
yyams
And therefore the output would be:
xamarin
xenophobia
xylophone
aardvark
apple
bagel
yams
zipper
So, what is happening is that, when the list is sorted, items that start with 'x'
will always appear before any other items.