Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort list of string based on number in string [duplicate]

For example I have list

my_list= ['image101.jpg', 'image2.jpg', 'image1.jpg']

and

my_list.sort()

gives me

['image1.jpg', 'image101.jpg', 'image2.jpg']

but I of course need

['image1.jpg', 'image2.jpg', 'image101.jpg']

How it can be done?

like image 537
mrgloom Avatar asked Mar 28 '16 09:03

mrgloom


People also ask

How do you sort a string with a number inside in Python?

To do this we can use the extra parameter that sort() uses. This is a function that is called to calculate the key from the entry in the list. We use regex to extract the number from the string and sort on both text and number.

How do you sort a list with numbers and letters in Python?

Use the Python List sort() method to sort a list in place. The sort() method sorts the string elements in alphabetical order and sorts the numeric elements from smallest to largest. Use the sort(reverse=True) to reverse the default sort order.


3 Answers

list.sort accepts optional key function. Each item is passed to the function, and the return value of the function is used to compare items instead of the original values.

>>> my_list= ['image101.jpg', 'image2.jpg', 'image1.jpg']
>>> my_list.sort(key=lambda x: int(''.join(filter(str.isdigit, x))))
>>> my_list
['image1.jpg', 'image2.jpg', 'image101.jpg']

filter, str.isdigit were used to extract numbers:

>>> ''.join(filter(str.isdigit, 'image101.jpg'))
'101'
>>> int(''.join(filter(str.isdigit, 'image101.jpg')))
101
  • ''.join(..) is not required in Python 2.x
like image 119
falsetru Avatar answered Oct 14 '22 07:10

falsetru


Use a regex to pull the number from the string and cast to int:

import  re
r = re.compile("\d+")
l = my_list= ['image101.jpg', 'image2.jpg', 'image1.jpg']
l.sort(key=lambda x: int(r.search(x).group()))

Or maybe use a more specific regex including the .:

import  re

r = re.compile("(\d+)\.")
l = my_list= ['image101.jpg', 'image2.jpg', 'image1.jpg']
l.sort(key=lambda x: int(r.search(x).group()))

Both give the same output for you example input:

['image1.jpg', 'image2.jpg', 'image101.jpg']

If you are sure of the extension you can use a very specific regex:

 r = re.compile("(\d+)\.jpg$")
 l.sort(key=lambda x: int(r.search(x).group(1)))
like image 9
Padraic Cunningham Avatar answered Oct 14 '22 06:10

Padraic Cunningham


If you want to do this in the general case, I would try a natural sorting package like natsort.

from natsort import natsorted
my_list = ['image101.jpg', 'image2.jpg', 'image1.jpg']
natsorted(my_list)

Returns:

['image1.jpg', 'image2.jpg', 'image101.jpg']

You can install it using pip i.e. pip install natsort

like image 7
reupen Avatar answered Oct 14 '22 05:10

reupen