473,385 Members | 1,359 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

outline-style sorting algorithm

I have a need to sort a list of elements that represent sections of a
document in dot-separated notation. The built in sort does the wrong thing.
This seems a rather complex problem and I was hoping someone smarter than me
had already worked out the best way to approach this. For example, consider
the following list-
foo ['1.0', '1.0.1', '1.1.1', '1.2', '1.9', '1.10', '1.11', '1.20', '1.20.1',
'1.30'] foo.sort()
foo

['1.0', '1.0.1', '1.1.1', '1.10', '1.11', '1.2', '1.20', '1.20.1', '1.30',
'1.9']

Obviously 1.20.1 should be after 1.9 if we look at this as dot-delimited
integers, not as decimal numbers.

Does anyone have pointers to existing code?


Jul 18 '05 #1
5 1526
jw**********@ramprecision.com wrote:
I have a need to sort a list of elements that represent sections of a
document in dot-separated notation. The built in sort does the wrong thing.

Not really. You are giving it a list of strings, and it sort those
alphabetically. That seems like the right thing to me ;-)
This seems a rather complex problem and I was hoping someone smarter than me had already worked out the best way to approach this. For example, consider the following list-

foo


['1.0', '1.0.1', '1.1.1', '1.2', '1.9', '1.10', '1.11', '1.20', '1.20.1',
'1.30']


You need to convert them to another datatype first. Your best bet here
would be a list or a tuple, as they can map directly to your data.

'1.0.1'.split('.') == [1,0,1]

But list are a bit easier here.

foo_as_tuples = [f.split('.') for f in foo]
foo_as_tuples.sort()

Then you must convert it back to strings again.

foo = ['.'.join(f) for f in foo_as_tuples]

There is a standard way of sorting quickly in python, called
decorate-sort-undecorate. It is allmost the same example as before:
decorated = [(itm.split('.'),itm) for itm in foo]
decorated.sort()
foo = [d[-1] for d in decorated]

regards Max M
Jul 18 '05 #2
Max M wrote:
jw**********@ramprecision.com wrote:
> I have a need to sort a list of elements that represent sections of a
> document in dot-separated notation. The built in sort does the wrong

thing.

Not really. You are giving it a list of strings, and it sort those
alphabetically. That seems like the right thing to me ;-)
> This seems a rather complex problem and I was hoping someone smarter

than me
> had already worked out the best way to approach this. For example,

consider
> the following list-

>>>>foo

>
> ['1.0', '1.0.1', '1.1.1', '1.2', '1.9', '1.10', '1.11', '1.20',

'1.20.1',
> '1.30']


You need to convert them to another datatype first. Your best bet here
would be a list or a tuple, as they can map directly to your data.

'1.0.1'.split('.') == [1,0,1]

[snip]

Nope:
'1.0.1.split('.') == ['1', '0', '1']

So the int's are still represented as strings and it does not solve the OP's
problem:
foo = ['1.0', '1.0.1', '1.1.1', '1.2', '1.9', '1.10', '1.11', '1.20', '1.20.1', '1.30'] bar = [x.split('.') for x in foo]
bar [['1', '0'], ['1', '0', '1'], ['1', '1', '1'], ['1', '2'], ['1', '9'], ['1',
'10'], ['1', '11'], ['1', '20'], ['1', '20', '1'], ['1', '30']] bar.sort()
bar [['1', '0'], ['1', '0', '1'], ['1', '1', '1'], ['1', '10'], ['1', '11'], ['1',
'2'], ['1', '20'], ['1', '20', '1'], ['1', '30'], ['1', '9']]

And the 1.20.something are still before 1.9

What you need to do is explicitely convert to integers the strings in the list
resulting from the split. Here is the shortest way to do it
bar = [map(int, x.split('.')) for x in foo]
bar [[1, 0], [1, 0, 1], [1, 1, 1], [1, 2], [1, 9], [1, 10], [1, 11], [1, 20], [1,
20, 1], [1, 30]]

Now you can sort:
bar.sort()
bar [[1, 0], [1, 0, 1], [1, 1, 1], [1, 2], [1, 9], [1, 10], [1, 11], [1, 20], [1,
20, 1], [1, 30]]

Hooray! We've got the result we wanted. Now, convert integers back to string and
re-join everything:
foo = ['.'.join(map(str, x)) for x in bar]
foo

['1.0', '1.0.1', '1.1.1', '1.2', '1.9', '1.10', '1.11', '1.20', '1.20.1', '1.30']

That's what we expected...

HTH
--
- Eric Brunel <eric (underscore) brunel (at) despammed (dot) com> -
PragmaDev : Real Time Software Development Tools - http://www.pragmadev.com

Jul 18 '05 #3
jw**********@ramprecision.com wrote:
I have a need to sort a list of elements that represent sections of a
document in dot-separated notation. The built in sort does the wrong thing.

Not really. You are giving it a list of strings, and it sort those
alphabetically. That seems like the right thing to me ;-)
This seems a rather complex problem and I was hoping someone smarter than me had already worked out the best way to approach this. For example, consider the following list-

foo


['1.0', '1.0.1', '1.1.1', '1.2', '1.9', '1.10', '1.11', '1.20', '1.20.1',
'1.30']


You need to convert them to another datatype first. Your best bet here
would be a list or a tuple, as they can map directly to your data.

'1.0.1'.split('.') == [1,0,1]

But list are a bit easier here.

foo_as_tuples = [f.split('.') for f in foo]
foo_as_tuples.sort()

Then you must convert it back to strings again.

foo = ['.'.join(f) for f in foo_as_tuples]

There is a standard way of sorting quickly in python, called
decorate-sort-undecorate. It is allmost the same example as before:
decorated = [(itm.split('.'),itm) for itm in foo]
decorated.sort()
foo = [d[-1] for d in decorated]

regards Max M

Jul 18 '05 #4
jw**********@ramprecision.com wrote:
I have a need to sort a list of elements that represent sections of a
document in dot-separated notation. The built in sort does the wrong thing.
This seems a rather complex problem and I was hoping someone smarter than me
had already worked out the best way to approach this. For example, consider
the following list-

foo
['1.0', '1.0.1', '1.1.1', '1.2', '1.9', '1.10', '1.11', '1.20', '1.20.1',
'1.30']
foo.sort()
foo


['1.0', '1.0.1', '1.1.1', '1.10', '1.11', '1.2', '1.20', '1.20.1', '1.30',
'1.9']

Obviously 1.20.1 should be after 1.9 if we look at this as dot-delimited
integers, not as decimal numbers.

Does anyone have pointers to existing code?




list = ['1.0', '1.0.1', '1.1.1', '1.2', '1.9', '1.10', '1.11', '1.20',
'1.20.1','1.30']

def parse(str):
list = str.split('.')
if len(list) > 0:
x1 = int(list[0])
else:
x1 = -1
if len(list) > 1:
x2 = int(list[1])
else:
x2 = -1
if len(list) > 2:
x3 = int(list[2])
else:
x3 = -1
return x1,x2,x3

def cmp(x1,x2):
w1 = parse(x1)
w2 = parse(x2)
if w1[0] < w2[0]:
return -1
if w1[0] > w2[0]:
return 1

if w1[1] < w2[1]:
return -1
if w1[1] > w2[1]:
return 1

if w1[2] < w2[2]:
return -1
if w1[2] > w2[2]:
return 1

return 0

#---------------------------
if __name__ == "__main__":
list.sort(cmp)
for x in list:
print x

Jul 18 '05 #5
* jw**********@ramprecision.com (2004-04-19 15:08 +0100)
I have a need to sort a list of elements that represent sections of a
document in dot-separated notation. The built in sort does the wrong thing.
This seems a rather complex problem and I was hoping someone smarter than me
had already worked out the best way to approach this. For example, consider
the following list-
foo ['1.0', '1.0.1', '1.1.1', '1.2', '1.9', '1.10', '1.11', '1.20', '1.20.1',
'1.30'] foo.sort()
foo

['1.0', '1.0.1', '1.1.1', '1.10', '1.11', '1.2', '1.20', '1.20.1', '1.30',
'1.9']

Obviously 1.20.1 should be after 1.9 if we look at this as dot-delimited
integers, not as decimal numbers.


You need some general approach to avoid the DSU thing:

def funcsort(seq, func):
""" sort seq by func(item) """
seq = seq[:]
seq.sort(lambda x, y: cmp(func(x), func(y)))
return seq

funcsort(foo, lambda x: map(int, x.split('.')))
Thorsten
Jul 18 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Xavier Noria | last post by:
A Google search here for folding Python code in Emacs pointed to outline.el, but when I try to use some *-hide-* commands I get "Wrong type argument: stringp, nil". The header of the file has no...
10
by: Agent Mulder | last post by:
I feel the need for an outline specifier to facilitate java-style programming.
3
by: NONYA | last post by:
This is driving me crazy. I'm having trouble with how a simple radio button is displayed, in a simple html form. The default has the outline around the radio button shaded gray only in the top...
4
by: Doors of Perception | last post by:
As you probably know, when you click on a link in MSIE and go to a page, then when you click the "back" button, you see a dotted box outlining the link on which I just clicked. As far as I'm...
1
by: John Doe | last post by:
I collapse an outline block, then copy it, then paste it. In my experience, the outline block always expands after the paste. Is their a way to modify the editor's behavior so that an outline block...
3
by: msnews.microsoft.com | last post by:
Anyone ever play with Outline views in VS.NET? I'm amazed I never discovered this. None of this was ever discussed in my training. It's a big help to use this with HTML view. View/Synchronize...
3
by: Kevin L | last post by:
I am dragging Panel controls on a form (run-time). I am looking for a way to show an outline that is the size of the panel so the user can position the panel accurately. Is there a way to show...
4
by: Rex | last post by:
Hi - I am new to VB.Net/2005, but not VB. I am trying to find an outline or tree - type control for VB.Net/2005 that provides the ability for the User to TYPE in one of the NODES of the outline......
2
by: Joel Byrd | last post by:
I want to get a red outline around different divs on a page when I hover the mouse over them, and then have the red outline disappear on mouse out (basically to indicate that various elements on...
0
by: 1001 Webs | last post by:
As I read at: http://webpages.charter.net/edreamleo/front.html Leo is... * A general data management environment. Leo shows user-created relationships among any kind of data: computer...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.