1

I have atext file and which contains the following:

02.03.04@@
02.04.01@@
02.04.03.02@@
02.06.04.01@@
02.06.04.02@@
02.06.09@@
02.13.01@@
02.13.02@@
1.01@@
1.02@@
1.03@@
1.04@@
1.05@@
1.06@@
1.07@@
1.08@@
1.09@@
1.1@@
2.24@@
4.12@@

I need to sort it .As you see numbers starting with 1, 2 etc are already sorted using sorted().but numbers like '02.04.03.02@@'are sorted seperately But logically it should be after 1. How to do this in Python ? do i split at '.' and then compare individually?

2 Answers 2

6

Split and map to integers in a key:

sorted(inputlist, key=lambda v: [int(i) for i in v.rstrip('@').split('.')])

This produces a list of integers for each line, and these are then sorted lexicographically; e.g. on the first element that differs.

Demo:

>>> sample = '''\
... 02.03.04@@
... 02.04.01@@
... 02.04.03.02@@
... 02.06.04.01@@
... 02.06.04.02@@
... 02.06.09@@
... 02.13.01@@
... 02.13.02@@
... 1.01@@
... 1.02@@
... 1.03@@
... 1.04@@
... 1.05@@
... 1.06@@
... 1.07@@
... 1.08@@
... 1.09@@
... 1.1@@
... 2.24@@
... 4.12@@
... '''.splitlines()
>>> from pprint import pprint
>>> sorted(sample, key=lambda v: [int(i) for i in v.rstrip('@').split('.')])
['1.01@@', '1.1@@', '1.02@@', '1.03@@', '1.04@@', '1.05@@', '1.06@@', '1.07@@', '1.08@@', '1.09@@', '02.03.04@@', '02.04.01@@', '02.04.03.02@@', '02.06.04.01@@', '02.06.04.02@@', '02.06.09@@', '02.13.01@@', '02.13.02@@', '2.24@@', '4.12@@']
>>> pprint(_)
['1.01@@',
 '1.1@@',
 '1.02@@',
 '1.03@@',
 '1.04@@',
 '1.05@@',
 '1.06@@',
 '1.07@@',
 '1.08@@',
 '1.09@@',
 '02.03.04@@',
 '02.04.01@@',
 '02.04.03.02@@',
 '02.06.04.01@@',
 '02.06.04.02@@',
 '02.06.09@@',
 '02.13.01@@',
 '02.13.02@@',
 '2.24@@',
 '4.12@@']
Sign up to request clarification or add additional context in comments.

13 Comments

Would key=lambda x: float(x.rstrip("@")) be an acceptable alternative to the list of ints?
@inspectorG4dget: no, because there are numbers with 3 components here, which are not valid float numbers.
When am trying in the code its throwing " ValueError: invalid literal for int() with base 10: '\x02'" @MartijinPieters
@nij_wiz: you have additional characters in your data you did not include in your question. What does print repr(line) produce for the line that throws that exception?
|
0

A very close variant of Martijn's answer can be used for a slightly different (and probably more common) use case of sorting numbers-as-strings according to an outline numbering system, such as for decimal-based hierarchical headings. For example, heading numbers in a legal contract or for book chapters/sections/subsections.

>>> unordered_headings = ['3.1', '1.2.2', '1.2.1', '2.5', '3', '2.4', '1.1', '1', '2', '2.10', '2.2', '2.3', '2.6', '2.11', '2.8', '2.9', '2.7', '1.2', '2.1']
>>> ordered_headings = sorted(unordered_headings, key=lambda v: [int(i) for i in v.split('.')])
>>> ordered_headings
['1', '1.1', '1.2', '1.2.1', '1.2.2', '2', '2.1', '2.2', '2.3', '2.4', '2.5', '2.6', '2.7', '2.8', '2.9', '2.10', '2.11', '3', '3.1']
>>> from pprint import pprint
>>> pprint(_)
['1',    
 '1.1',  
 '1.2',  
 '1.2.1',
 '1.2.2',
 '2',    
 '2.1',  
 '2.2',  
 '2.3',  
 '2.4',
 '2.5',
 '2.6',
 '2.7',
 '2.8',
 '2.9',
 '2.10',
 '2.11',
 '3',
 '3.1']
>>>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.