How to Sort a List of Strings Numerically

How to sort a list of strings numerically?

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)

Sorting a list of strings numerically

Yes:

flist.sort(key=lambda fname: int(fname.split('.')[0]))

Explanation: strings are lexically sorted so "10" comes before "3" (because "1" < "3", so whatever comes after "1" in the first string is ignored). So we use list.sort()'s key argument which is a callback function that takes a list item and return the value to be used for ordering for this item - in your case, an integer built from the first part of the filename. This way the list is properly sorted on the numerical values.

How to sort python list of strings of numbers

You want to sort based on the float values (not string values), so try:

>>> b = ["949.0","1099.0"]
>>> b.sort(key=float)
>>> b
['949.0', '1099.0']

Sorting a list of strings based on numeric order of numeric part

You could use the re module to split each string into a tuple of characters and grouping the digits into one single element. Something like r'(\d+)|(.)'. The good news with this regex is that it will return separately the numeric and non numeric groups.

As a simple key, we could use:

def key(x):
# the tuple comparison will ensure that numbers come before letters
return [(j, int(i)) if i != '' else (j, i)
for i, j in re.findall(r'(\d+)|(.)', x)]

Demo:

lst = ['a1a', 'a2a', 'a5b', 'a10a', 'b1a', 'abc']
print(sorted(lst, key=key)

gives:

['a1a', 'a2a', 'a5b', 'a10a', 'abc', 'b1a']

If you want a more efficient processing, we could compile the regex only once in a closure

def build_key():
rx = re.compile(r'(\d+)|(.)')
def key(x):
return [(j, int(i)) if i != '' else (j, i)
for i, j in rx.findall(x)]
return key

and use it that way:

sorted(lst, key=build_key())

giving of course the same output.

How do I sort a list of string and numbers in numerical order?

Since your listId is String ,the list gets sorted lexographically. Instead you could first convert the String to an Integer and then sort it. Below is the illustration.

Collections.sort(tempList, (mainData, t1) -> Integer.parseInt(mainData.getListId())-Integer.parseInt(t1.getListId());

How to correctly sort a string with a number inside?

Perhaps you are looking for human sorting (also known as natural sorting):

import re

def atoi(text):
return int(text) if text.isdigit() else text

def natural_keys(text):
'''
alist.sort(key=natural_keys) sorts in human order
http://nedbatchelder.com/blog/200712/human_sorting.html
(See Toothy's implementation in the comments)
'''
return [ atoi(c) for c in re.split(r'(\d+)', text) ]

alist=[
"something1",
"something12",
"something17",
"something2",
"something25",
"something29"]

alist.sort(key=natural_keys)
print(alist)

yields

['something1', 'something2', 'something12', 'something17', 'something25', 'something29']

PS. I've changed my answer to use Toothy's implementation of natural sorting (posted in the comments here) since it is significantly faster than my original answer.


If you wish to sort text with floats, then you'll need to change the regex from one that matches ints (i.e. (\d+)) to a regex that matches floats:

import re

def atof(text):
try:
retval = float(text)
except ValueError:
retval = text
return retval

def natural_keys(text):
'''
alist.sort(key=natural_keys) sorts in human order
http://nedbatchelder.com/blog/200712/human_sorting.html
(See Toothy's implementation in the comments)
float regex comes from https://stackoverflow.com/a/12643073/190597
'''
return [ atof(c) for c in re.split(r'[+-]?([0-9]+(?:[.][0-9]*)?|[.][0-9]+)', text) ]

alist=[
"something1",
"something2",
"something1.0",
"something1.25",
"something1.105"]

alist.sort(key=natural_keys)
print(alist)

yields

['something1', 'something1.0', 'something1.105', 'something1.25', 'something2']

How to sort string with numbers in it numerically?

I think

val sortedList = data.sortedWith(compareBy(
{ it.listId },
{ it.name.substring(0, it.name.indexOf(' ')) },
{ it.name.substring(it.name.indexOf(' ') + 1).toInt() }
))

will work but it is not computationally efficient because it will call String.indexOf() many times.

If you have a very long list, you should consider making another list whose each item has String and Int names.

How to sort a list of strings by prefix number then alphabetically

So you have to split your strings into an (optional) numeric part and an (optional) rest. This can be done by a Regex:

var match = Regex.Match(item, @"(?<number>\d+)?(?<rest>.*)$");

The "number" part matches one or more digits, but is optional (question mark), the "rest" part matches the whole rest of the string.

Sorting via Linq:

var input = new List<string>{ "12a", "1", "1a", "2", "2a", "2b", "a", "b", "12a" };
var sorted = input.OrderBy(item =>
{
var match = Regex.Match(item, @"(?<number>\d+)?(?<rest>.*)$");
return Tuple.Create(match.Groups["number"].Success ? int.Parse(match.Groups["number"].Value) : -1, match.Groups["rest"].Value);
}).ToList();

(I deliberately decided to put the items without a leading number before the rest; this was not specified in the question).

Output: a, b, 1, 1a, 2, 2a, 2b, 12a

Python - sorting strings numerically

You could try to parse the first field as int with:

readdetails.sort(key=lambda x: int(x.split()[0]))

This will work well if all lines are in a consistent format.

Otherwise use a more complex function as a key function for list.sort(), e.g.:

def extract_id(line):
# do something with line
# and return an integer, or another kind of value

and pass it to sort function:

readdetails.sort(key=extract_id)


Related Topics



Leave a reply



Submit