Reputation: 2860
I have a list that I need to sort
list_of_sent = ['a5 abc xyz','w1 3 45 7','a6 abc deg','r4 2 7 9']
The rules are as follows.
In the above example, the expected output is
['a5 abc deg','a6 abc xyz','r4 2 7 9','w1 3 45 7']
I understand this is some form of indirect sorting but not sure how to approach that. So far, I have separated the list in terms of whether the 2nd and onward items have numbers or not. But not sure how to proceede after that.
def reorderLines(logLines):
numList = []
letterList = []
hashMap = {}
for item in logLines:
words = item.split()
key= words[0]
hashMap[key] = item
if words[1].isdigit():
numList.append(item)
else:
letterList.append(item)
#sort each list individually
print(numList)
print(letterList)
EDIT:
This will output
['a5 abc xyz','a6 abc deg']
['w1 3 45 7','r4 2 7 9']
How do I proceed afterwards to reach to the output of
['a5 abc deg','a6 abc xyz','r4 2 7 9','w1 3 45 7']
Upvotes: 0
Views: 594
Reputation: 10989
We can write sorting key as follows:
def sorting_key(element):
second_substring = element.split()[1]
return second_substring.isdecimal(), element
then use it in sorted
builtin like
>>> list_of_sent = ['a5 abc xyz', 'w1 3 45 7', 'a6 abc deg', 'r4 2 7 9']
>>> sorted(list_of_sent, key=sorting_key)
['a5 abc xyz', 'a6 abc deg', 'r4 2 7 9', 'w1 3 45 7']
or if we don't need old order we can sort list_of_sent
in place (may be more efficient, at least will not occupy additional memory for a new list
):
>>> list_of_sent = ['a5 abc xyz', 'w1 3 45 7', 'a6 abc deg', 'r4 2 7 9']
>>> list_of_sent.sort(key=sorting_key)
>>> list_of_sent
['a5 abc xyz', 'a6 abc deg', 'r4 2 7 9', 'w1 3 45 7']
More info about differences between sorted
& list.sort
could be found in this thread.
Upvotes: 2
Reputation: 183
After the comment do these:
newlist = []
numList.sort()
letterList.sort()
newlist = letterList + numList
print(numList)
print (letterList)
print (newlist)
Upvotes: 0
Reputation: 365925
The answer to your direct question is simple.
You've already worked out how to split the list into these two lists:
['a5 abc xyz','a6 abc deg']
['w1 3 45 7','r4 2 7 9']
Now, you just need to sort each one, and add them together.
But this really isn't the right approach in the first place. When looking at how to do a custom sort, the first thing you should do is ask yourself whether some other list, which you could easily transform this one into, would be trivial to sort.
For example, imagine you had this:
list_of_sent = [
(False, 'a5 abc xyz'),
(True, 'w1 3 45 7'),
(False, 'a6 abc deg'),
(True, 'r4 2 7 9')]
… where that first value in each tuple is True
iff the second word in the string is a number.
If that were your list, you could just call sort
or sorted
on it, and you'd be done.
So, can you transform each of your strings into a tuple like that? Sure you can:
def flagnumbers(words):
isnumber = words.split()[1].isdigit()
return isnumber, words
And how, you can just pass that as the key
function to sort your list:
list_of_sent = ['a5 abc xyz','w1 3 45 7','a6 abc deg','r4 2 7 9']
print(sorted(list_of_sent, key=flagnumbers))
That's it.
The Sorting HOWTO in the docs covers key functions in more detail, with some nice examples.
Upvotes: 3