Compare two python lines that contain numbers

UPDATE: I should have asked this before, but not all names just float. For example, some of them are "prefixed" with "YT". So, for example, "YT1.1. So, you have the same problem: YT1.9 <YT1.11 should be true. I am really surprised that string comparisons are not performed ....

hi, this should be a fairly simple question, but I can not find the answer. I would like to sort the list of XL worksheets by name. Each of the names is numbers, but just like the “sections” of the textbook are numbered, which means that section 4.11 comes after 4.10, which both appear after 4.9 and 4.1. I thought of simply comparing these numbers as a string, but I get the following:

>>> s1 = '4.11' >>> s2 = '4.2' >>> s1> s2 False >>> n1 = 4.11 >>> n2 = 4.2 >>> n1 > n2 False 

How can I compare these two values ​​so that 4.11 is greater than 4.2?

+4
source share
5 answers

Convert names to tuples of integers and compare tuples:

 def splittedname(s): return tuple(int(x) for x in s.split('.')) splittedname(s1) > splittedname(s2) 

Refresh . Since your names can apparently contain characters other than numbers, you need to check the ValueError and leave any values ​​that cannot be converted to int without changes:

 import re def tryint(x): try: return int(x) except ValueError: return x def splittedname(s): return tuple(tryint(x) for x in re.split('([0-9]+)', s)) 

To sort the list of names, use splittedname as the key function for sorted :

 >>> names = ['YT4.11', '4.3', 'YT4.2', '4.10', 'PT2.19', 'PT2.9'] >>> sorted(names, key=splittedname) ['4.3', '4.10', 'PT2.9', 'PT2.19', 'YT4.2', 'YT4.11'] 
+10
source

This is not a built-in method, but it should work:

 >>> def lt(num1, num2): ... for a, b in zip(num1.split('.'), num2.split('.')): ... if int(a) < int(b): ... return True ... if int(a) > int(b): ... return False ... return False ... ... lt('4.2', '4.11') 0: True 

It can be cleansed, but it gives you the gist.

+1
source

What you are looking for is called "natural sorting." This contradicts the “lexicographic sorting”. There are several recipes that do this, since the exact conclusion of what you want depends on the implementation. A quick google search gives this (note that this is not my code, and I have not tested it):

 import re def tryint(s): try: return int(s) except: return s def alphanum_key(s): """ Turn a string into a list of string and number chunks. "z23a" -> ["z", 23, "a"] """ return [ tryint(c) for c in re.split('([0-9]+)', s) ] def sort_nicely(l): """ Sort the given list in the way that humans expect. """ l.sort(key=alphanum_key) 

http://nedbatchelder.com/blog/200712.html#e20071211T054956

+1
source

use s1.split(".") to create a list of items before and after the decimal, then sort the list of lists, for example:

 import random sheets = list([str(x), str(y)] for x in xrange(1, 5) for y in xrange(0,99)) print sheets #sheets in order random.shuffle(sheets) print sheets #sheets out of order sheets.sort() print sheets #sheets back in order 

So, the implementation may be:

 #assume input sheets is a list of the worksheet names sheets = list(x.split(".") for x in input_sheets) sheets.sort() 
0
source

If you know that they are real numbers [*], simply:

 >>> float(s1) > float(s2) True 

[*] Otherwise, be prepared to handle the raised ValueError .

-2
source

All Articles