PYTHON natsort

is this article helpful?
|
Python replacement for PHP's natsort [ edit | history ]
There are many variants for a natsort replacement out there. Have a look at: http://code.activestate.com/recipes/285264-natural-string-sorting/

My own version (for php 2.6.x only) looks like this:

def natsort26(seq, casei=True, reverse=False):
	import re
	def get_segments(value):
			segments = []
			for string in re.findall("\D+|\d+", str(value)):
				if casei: string = string.lower()
				try:	segment=int(string)
				except: segment = string
				segments.append(segment)
			return segments
	return sorted(seq, key=get_segments, reverse=reverse)


a = ["a10","b10","Aa11","b1","b2","b6",10,356,"aa11bb22"]

print(natsort26(a))
[10, 356, 'a10', 'Aa11', 'aa11bb22', 'b1', 'b2', 'b6', 'b10']
print(natsort26(a,False)) # be case sensitive ...
[10, 356, 'Aa11', 'a10', 'aa11bb22', 'b1', 'b2', 'b6', 'b10']
print(natsort26(a,False,True)) # ... and sort in reverse order
['b10', 'b6', 'b2', 'b1', 'aa11bb22', 'a10', 'Aa11', 356, 10]


Since str and int cannot be compared against each other in python3, the function for python3 needs a little (ugly) correction, to make integers sortable as string:

def natsort3(seq,casei=True,reverse=False):
	import re
	stuffitinpython3=1
	for value in seq:
			for string in (string.group(0) if casei == False else string.group(0).lower()\
						for string in re.finditer("\D+|\d+", str(value))):
				try:
					segment=[int(string)]
					stuffitinpython3 = max (stuffitinpython3,len(string))
				except: segment = [string]
				try: segments = segments+segment
				except: segments = segment
				try: segment_length = max(segment_length,len(segments))
				except: segment_length = len(segments)
			try: newseq.append([value]+segments)
			except: newseq = [[value]+segments]
			del segments,segment
	for layer in range(1,segment_length+1):
		for index in range(0,len(newseq)):
			try:
				try: newseq[index][layer] = ("%."+str(stuffitinpython3)+"d") % (newseq[index][layer])
				except: newseq[index][layer]
			except: newseq[index].insert(layer, ("%."+str(stuffitinpython3)+"d") % 0)
	for layer in range(segment_length,0,-1):
		newseq.sort(key=lambda a: a[layer],reverse=reverse)
	return [value[0] for value in newseq]


(natsort3 is working with python 2.6.x as well)

PHP natsort

PHP original manual for natsort [ show | php.net ]

natsort

(PHP 4, PHP 5)

natsortSort an array using a "natural order" algorithm

Description

bool natsort ( array &$array )

This function implements a sort algorithm that orders alphanumeric strings in the way a human being would while maintaining key/value associations. This is described as a "natural ordering". An example of the difference between this algorithm and the regular computer string sorting algorithms (used in sort()) can be seen in the example below.

Parameters

array

The input array.

Return Values

Returns TRUE on success or FALSE on failure.

Examples

Example #1 natsort() example

<?php
$array1 
$array2 = array("img12.png""img10.png""img2.png""img1.png");

sort($array1);
echo 
"Standard sorting\n";
print_r($array1);

natsort($array2);
echo 
"\nNatural order sorting\n";
print_r($array2);
?>

The above example will output:

Standard sorting
Array
(
    [0] => img1.png
    [1] => img10.png
    [2] => img12.png
    [3] => img2.png
)

Natural order sorting
Array
(
    [3] => img1.png
    [2] => img2.png
    [1] => img10.png
    [0] => img12.png
)

For more information see: Martin Pool's » Natural Order String Comparison page.

See Also

  • natcasesort() - Sort an array using a case insensitive "natural order" algorithm
  • strnatcmp() - String comparisons using a "natural order" algorithm
  • strnatcasecmp() - Case insensitive string comparisons using a "natural order" algorithm