1

My problem is really weird. I have to sort an list like:

list1=["S01E01","S02E010", "S02E013", "S02E02", "S02E03"]

and I want result like:

list1=["S01E01","S02E02", "S02E03", "S02E010", "S02E013"]

I used sort(), sorted(), map() methods but these methods couldn't sort this list as it is already sorted. If you type "010">"02" in python console it will return false.

Please suggest me any way to debug this problem.

See the console screenshots

martineau
  • 119,623
  • 25
  • 170
  • 301
  • 5
    It sounds like you want *natural sorting* - https://stackoverflow.com/questions/4836710/does-python-have-a-built-in-function-for-string-natural-sort should answer your question? – Jon Clements Feb 08 '20 at 07:20

4 Answers4

1

To do this you need use a key function that splits the string up into components and returns them as a tuple. Any substring that's a number should be converted into an integer if you want it's value to be considered numerically, otherwise it will be lexicographically (alphabetical).

Bases on the sample data, I think doing that would be like this:

def keyfunc(s):
    return s[0], int(s[1:3]), s[3], int(s[4:])

list1 = ["S01E01","S02E010", "S02E013", "S02E02", "S02E03"]

result = sorted(list1, key=keyfunc)
print(result)  # -> ['S01E01', 'S02E02', 'S02E03', 'S02E010', 'S02E013']
martineau
  • 119,623
  • 25
  • 170
  • 301
  • If a series has more than 100 seasons then it wouldn't be right? But It's unrealistic at the same time to have 100 seasons. – Ch3steR Feb 08 '20 at 07:45
  • @Ch3steR: I implemented the splitting based on the sample strings with no description of the the "fields" might mean or what the range was of the numerical ones. Depending on what the pattern actually is, the splitting could become more complicated and might require something like a regex to parse — but the basic idea remains the same. – martineau Feb 08 '20 at 08:04
  • Yes, I'm not saying the answer is bad. But **OP** should mention the constraints on the data like *there is no series with more than 20 seasons*. IMO we can give a more optimized and efficient solution only if we understand the data and the constraints involved. Sometimes generic solutions are less efficient but it does give the idea of how to do things. +1. – Ch3steR Feb 08 '20 at 08:08
0
import re
def key(op):
    return list(map(int, re.match('S(\d+)E(\d+)', op).groups()))

list1 = sorted(list1, key=key)
Yriuns
  • 755
  • 1
  • 8
  • 22
0

you could use a regular expression to extract the numbers from your string and place them in a tuple because when you are sorting the numbers the tuples are sorted base on the values from ascending index (by first value than second value and so on):

import re

def key(s):
    return tuple(map(int, re.findall(r'\d+', s)))

list1.sort(key=key)
list1

output:

['S01E01', 'S02E02', 'S02E03', 'S02E010', 'S02E013']
kederrac
  • 16,819
  • 6
  • 32
  • 55
-1

try this:

list1=["S01E01","S02E010", "S02E013", "S02E02", "S02E03"]
list1.sort(key = lambda x: int(x[1:3] + x[4:]))

o/p:

['S01E01', 'S02E02', 'S02E03', 'S02E010', 'S02E013']
Faizan Naseer
  • 589
  • 3
  • 12