My aim is to sort a list of strings where words have to be sorted alphabetically.Except words starting with "s" should be at the start of the list (they should be sorted as well), followed by the other words.
The below function does that for me.
def mysort(words):
mylist1 = sorted([i for i in words if i[:1] == "s"])
mylist2 = sorted([i for i in words if i[:1] != "s"])
list = mylist1 + mylist2
return list
I am just looking for alternative approaches to achieve this or if anyone can find any issues with the code above.
You could do it in one line, with:
sorted(words, key=lambda x: 'a' + x if x.startswith('s') else 'b' + x)
The sorted()
function takes a keyword argument key
, which is used to translate the values in the list before comparisons are done.
For example:
sorted(words, key=str.lower)
# Will do a sort that ignores the case, since instead
# of checking 'A' vs. 'b' it will check str.lower('A')
# vs. str.lower('b').
sorted(intlist, key=abs)
# Will sort a list of integers by magnitude, regardless
# of whether they're negative or positive:
# >>> sorted([-5,2,1,-8], key=abs)
# [1, 2, -5, -8]
The trick I used translated strings like this when doing the sorting:
"hello" => "bhello"
"steve" => "asteve"
And so "steve" would come before "hello" in the comparisons, since the comparisons are done with the a/b
prefix.
Note that this only affects the keys used for comparisons, not the data items that come out of the sort.
1 . You can use generator expression
inside sorted
.
2 . You can use str.startswith
.
3 . Don't use list
as a variable name.
4 . Use key=str.lower
in sorted.
mylist1 = sorted((i for i in words if i.startswith(("s","S"))),key=str.lower)
mylist2 = sorted((i for i in words if not i.startswith(("s","S"))),key=str.lower)
return mylist1 + mylist2
why str.lower
?
>>> "abc" > "BCD"
True
>>> "abc" > "BCD".lower() #fair comparison
False
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