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.
Sort string by multiple separated numbers
Try with sorted
, supplying a custom key that uses re
to extract all numbers from the path:
import re
>>> sorted(paths, key=lambda x: list(map(int,re.findall("(\d+)", x))))
['apple1/banana1',
'apple1/banana2',
'apple2/banana1',
'apple2/banana2',
'apple10/banana1/carrot1',
'apple10/banana1/carrot2',
'apple10/banana2/carrot1']
Sort list of string based on number in string
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
How to sort first by letter then by number?
You can use a function to modify the sort key of each list item, without altering the original list
contents:
def sort_key(text: str):
letter = text[0] # the first char
digits = text[1:] # everything after the first char
return (letter, int(digits))
>>> sws = ['C6', 'A4', 'B8', 'A8', 'B11', 'C3', 'C5']
>>> sorted(sws, key=sort_key)
['A4', 'A8', 'B8', 'B11', 'C3', 'C5', 'C6']
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)
Is there a way to sort string lists by numbers inside of the strings?
You can sort the list like this:
hi.sort();
(because numbers sort before letters in its implementation)
How do I sort strings alphabetically while accounting for value when a string is numeric?
Pass a custom comparer into OrderBy. Enumerable.OrderBy will let you specify any comparer you like.
This is one way to do that:
void Main()
{
string[] things = new string[] { "paul", "bob", "lauren", "007", "90", "101"};
foreach (var thing in things.OrderBy(x => x, new SemiNumericComparer()))
{
Console.WriteLine(thing);
}
}
public class SemiNumericComparer: IComparer<string>
{
/// <summary>
/// Method to determine if a string is a number
/// </summary>
/// <param name="value">String to test</param>
/// <returns>True if numeric</returns>
public static bool IsNumeric(string value)
{
return int.TryParse(value, out _);
}
/// <inheritdoc />
public int Compare(string s1, string s2)
{
const int S1GreaterThanS2 = 1;
const int S2GreaterThanS1 = -1;
var IsNumeric1 = IsNumeric(s1);
var IsNumeric2 = IsNumeric(s2);
if (IsNumeric1 && IsNumeric2)
{
var i1 = Convert.ToInt32(s1);
var i2 = Convert.ToInt32(s2);
if (i1 > i2)
{
return S1GreaterThanS2;
}
if (i1 < i2)
{
return S2GreaterThanS1;
}
return 0;
}
if (IsNumeric1)
{
return S2GreaterThanS1;
}
if (IsNumeric2)
{
return S1GreaterThanS2;
}
return string.Compare(s1, s2, true, CultureInfo.InvariantCulture);
}
}
Related Topics
Calculate Time Difference Between Two Pandas Columns in Hours and Minutes
Change Working Directory in Shell with a Python Script
Allowing Ctrl-C to Interrupt a Python C-Extension
Running Python Script as a Systemd Service
Attribute Bold Doesn't Seem to Work in My Curses
How to Kill Zombie Processes Created by Multiprocessing Module
Opencv (Via Python) on Linux: Set Frame Width/Height
Faster Way to Find Large Files with Python
Typeerror: 'Str' Does Not Support the Buffer Interface
How to Remove List Elements in a For Loop in Python
Environment Variables When Script Run by Cron
Mismatch Between Sys.Executable and Sys.Version in Python
Python Memory Debugging with Gdb
Python:Undefined Symbol: Pyunicodeucs2_Decodeutf8