# How to sort a list of strings numerically?

## Question:

I know that this sounds trivial but I did not realize that the `sort()` function of Python was weird. I have a list of “numbers” that are actually in string form, so I first convert them to ints, then attempt a sort.

``````list1=["1","10","3","22","23","4","2","200"]
for item in list1:
item=int(item)

list1.sort()
print list1
``````

Gives me:

``````['1', '10', '2', '200', '22', '23', '3', '4']
``````

What I want is

``````['1','2','3','4','10','22','23','200']
``````

I’ve looked around for some of the algorithms associated with sorting numeric sets, but the ones I found all involve sorting alphanumeric sets.

I know this is probably a no brainer problem but google and my textbook don’t offer anything more or less useful than the `.sort()` function.

You could pass a function to the `key` parameter to the `.sort` method. With this, the system will sort by key(x) instead of x.

``````list1.sort(key=int)
``````

BTW, to convert the list to integers permanently, use the `map` function

``````list1 = list(map(int, list1))   # you don't need to call list() in Python 2.x
``````

or list comprehension

``````list1 = [int(x) for x in list1]
``````

You haven’t actually converted your strings to ints. Or rather, you did, but then you didn’t do anything with the results. What you want is:

``````list1 = ["1","10","3","22","23","4","2","200"]
list1 = [int(x) for x in list1]
list1.sort()
``````

If for some reason you need to keep strings instead of ints (usually a bad idea, but maybe you need to preserve leading zeros or something), you can use a key function. `sort` takes a named parameter, `key`, which is a function that is called on each element before it is compared. The key function’s return values are compared instead of comparing the list elements directly:

``````list1 = ["1","10","3","22","23","4","2","200"]
# call int(x) on each element before comparing it
list1.sort(key=int)
# or if you want to do it all in the same line
list1 = sorted([int(x) for x in list1])
``````

Python’s sort isn’t weird. It’s just that this code:

``````for item in list1:
item=int(item)
``````

isn’t doing what you think it is – `item` is not replaced back into the list, it is simply thrown away.

Anyway, the correct solution is to use `key=int` as others have shown you.

In case you want to use `sorted()` function: `sorted(list1, key=int)`

It returns a new sorted list.

The most recent solution is right. You are reading solutions as a string, in which case the order is 1, then 100, then 104 followed by 2 then 21, then 2001001010, 3 and so forth.

sorted strings:

`stringList = (1, 10, 2, 21, 3)`

sorted ints:

`intList = (1, 2, 3, 10, 21)`

To cast, just put the stringList inside int ( blahblah ).

Again:

``````stringList = (1, 10, 2, 21, 3)

newList = int (stringList)

print newList

=> returns (1, 2, 3, 10, 21)
``````
``````scores = ['91','89','87','86','85']
scores.sort()
print (scores)
``````

This worked for me using python version 3, though it didn’t in version 2.

You can also use:

``````import re

def sort_human(l):
convert = lambda text: float(text) if text.isdigit() else text
alphanum = lambda key: [convert(c) for c in re.split('([-+]?[0-9]*.?[0-9]*)', key)]
l.sort(key=alphanum)
return l
``````

This is very similar to other stuff that you can find on the internet but also works for alphanumericals like `[abc0.1, abc0.2, ...]`.

Seamus Campbell‘s answer doesn’t work on Python 2.x.

`list1 = sorted(list1, key=lambda e: int(e))` using `lambda` function works well.

I approached the same problem yesterday and found a module called natsort, which solves your problem. Use:

``````from natsort import natsorted # pip install natsort

# Example list of strings
a = ['1', '10', '2', '3', '11']

[In]  sorted(a)
[Out] ['1', '10', '11', '2', '3']

[In]  natsorted(a)
[Out] ['1', '2', '3', '10', '11']

# Your array may contain strings
[In]  natsorted(['string11', 'string3', 'string1', 'string10', 'string100'])
[Out] ['string1', 'string3', 'string10', 'string11', 'string100']
``````

It also works for dictionaries as an equivalent of `sorted`.

Simple way to sort a numerical list

``````numlists = ["5","50","7","51","87","97","53"]
results = list(map(int, numlists))
results.sort(reverse=False)
print(results)
``````

If you want to use strings of the numbers better take another list as shown in my code it will work fine.

``````list1=["1","10","3","22","23","4","2","200"]

k=[]
for item in list1:
k.append(int(item))

k.sort()
print(k)
# [1, 2, 3, 4, 10, 22, 23, 200]
``````

Try this, it’ll sort the list in-place in descending order (there’s no need to specify a key in this case):

Process

``````listB = [24, 13, -15, -36, 8, 22, 48, 25, 46, -9]
listC = sorted(listB, reverse=True) # listB remains untouched
print listC
``````

output:

`````` [48, 46, 25, 24, 22, 13, 8, -9, -15, -36]
``````

real problem is that sort sorts things alphanumerically. So if you have a list
[‘1’, ‘2’, ’10’, ’19’] and run sort you get [‘1′, ’10’. ’19’, ‘2’]. ie 10 comes before 2 because it looks at the first character and sorts starting from that.
It seems most methods in python return things in that order. For example if you have a directory named abc with the files labelled as 1.jpg, 2.jpg etc say up to 15.jpg and you do
file_list=os.listdir(abc) the file_list is not ordered as you expect but rather as
file_list=[‘1.jpg’, ’11.jpg’—’15.jpg’, ‘2.jpg]. If the order in which files are processed is
important (presumably that’s why you named them numerically) the order is not what you think it will be. You can avoid this by using “zeros” padding. For example if you have a list
alist=[’01’, ’03’, ’05’, ’10’, ’02’,’04’, ’06] and you run sort on it you get the order you
wanted. alist=[’01’, ’02’ etc] because the first character is 0 which comes before 1. The amount of zeros padding you need is determined by the largest value in the list.For example if the largest is say between 100 and 1000 you need to pad single digits as 001, 002 —010,011–100, 101 etc.

may be not the best python, but for string lists like
[‘1′,’1.0′,’2.0′,’2’, ‘1.1’, ‘1.10’, ‘1.11’, ‘1.2’,’7′,’3′,’5′]with the expected target
[‘1’, ‘1.0’, ‘1.1’, ‘1.2’, ‘1.10’, ‘1.11’, ‘2’, ‘2.0’, ‘3’, ‘5’, ‘7’] helped me…

``````unsortedList = ['1','1.0','2.0','2', '1.1', '1.10', '1.11', '1.2','7','3','5']
sortedList = []
sortDict = {}
sortVal = []
#set zero correct (integer): examp: 1.000 will be 1 and breaks the order
zero = "000"
for i in sorted(unsortedList):
x = i.split(".")
if x in sortDict:
if len(x) > 1:
sortVal.append(x)
else:
sortVal.append(zero)
sortDict[x] = sorted(sortVal, key = int)
else:
sortVal = []
if len(x) > 1:
sortVal.append(x)
else:
sortVal.append(zero)
sortDict[x] = sortVal
for key in sortDict:
for val in sortDict[key]:
if val == zero:
sortedList.append(str(key))
else:
sortedList.append(str(key) + "." + str(val))
print(sortedList)
``````
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.