Question on sorting

L

Lad

Hi,
I have a file of records of 4 fields each.
Each field is separated by a semicolon. That is

Filed1;Ffield2;Field3;Field4

But there may be also empty records such as
;;;;
(only semicolons).

For sorting I used
#################
lines = file('Config.txt').readlines()# a file I want to sort
lines.sort()
ff=open('ConfigSorted.txt','w')# sorted file
ff.writelines(lines)
ff.close()
###############
It was sorted but empty records were first. I need them to be last(at
the end of the file). How can I do that?

Thanks for help
Lad
 
W

wes weston

Lad said:
Hi,
I have a file of records of 4 fields each.
Each field is separated by a semicolon. That is

Filed1;Ffield2;Field3;Field4

But there may be also empty records such as
;;;;
(only semicolons).

For sorting I used
#################
lines = file('Config.txt').readlines()# a file I want to sort
lines.sort()
ff=open('ConfigSorted.txt','w')# sorted file
ff.writelines(lines)
ff.close()
###############
It was sorted but empty records were first. I need them to be last(at
the end of the file). How can I do that?

Thanks for help
Lad

Lad,
The sort call can have a function name as an arg. You
could do:

def mycompare(s1,s2):
#return -1 to put s1's at front; 1 to put s1's at back; 0 for a tie
#if s1==";;;;" and s2<>";;;;": return 1

lines.sort(mycompare)

wes
 
E

Eddie Corns

Lad,
The sort call can have a function name as an arg. You
could do:
def mycompare(s1,s2):
#return -1 to put s1's at front; 1 to put s1's at back; 0 for a tie
#if s1==";;;;" and s2<>";;;;": return 1
lines.sort(mycompare)

I can't help feeling that the OP might have really wanted to be sorting on
individual fields rather than whole lines. In which case I would think of
doing a line.split(';') on each line before sorting. It would still need
either to use a function to make empty fields go later or alternatively use
DSU (google!) and convert '' to say '~' and back again. This also solves the
problem of what to expect when only some of the fields are blank rather than
all of them.

Eddie
 
L

Lad

wes weston said:
Lad,
The sort call can have a function name as an arg. You
could do:

def mycompare(s1,s2):
#return -1 to put s1's at front; 1 to put s1's at back; 0 for a tie
#if s1==";;;;" and s2<>";;;;": return 1

lines.sort(mycompare)
Wes,
Thank you for reply. But I do not understand mycompare function. Can
you please explain to me how it should work? Thanks

LAd
 
P

Peter Otten

Lad said:
Wes,
Thank you for reply. But I do not understand mycompare function. Can
you please explain to me how it should work? Thanks

compare(a, b) is just a function for comparing two items/lines. I must
return -1 if a<b, +1 if a>b, and 0 if a==b. For example the following
compare moves the ";;;;" records to the end and keeps the order of others
unaffected:
items = [";;;;", ";a;b;;", ";b;a;;", "a;b;c;d;e", "a;;;d;e"]
def compare(a, b):
.... return cmp(a == ";;;;", b == ";;;;") or cmp(a, b)
....[';a;b;;', ';b;a;;', 'a;;;d;e', 'a;b;c;d;e', ';;;;']

As Eddie Corns pointed out, you left some doubt whether that is really what
you want. Here is a more complex compare() that handles the lines as
columns split by ";" and puts empty columns last in the sorting order:
.... return [(not col, col) for col in row.split(";")]
........ return cmp(key(a), key(b))
....['a;b;c;d;e', 'a;;;d;e', ';a;b;;', ';b;a;;', ';;;;']

If you are on Python 2.4, you don't need the compare() detour and can use
key() directly:
['a;b;c;d;e', 'a;;;d;e', ';a;b;;', ';b;a;;', ';;;;']

Finally, the ";;;;" lines don't seem to carry any information - why not
filter them out completely?
items = [line[:-1] for line in file("cfg.txt", "U") if line != ";;;;\n"]


Peter
 
L

Lad

Peter Otten said:
Lad said:
Wes,
Thank you for reply. But I do not understand mycompare function. Can
you please explain to me how it should work? Thanks

compare(a, b) is just a function for comparing two items/lines. I must
return -1 if a<b, +1 if a>b, and 0 if a==b. For example the following
compare moves the ";;;;" records to the end and keeps the order of others
unaffected:
items = [";;;;", ";a;b;;", ";b;a;;", "a;b;c;d;e", "a;;;d;e"]
def compare(a, b):
... return cmp(a == ";;;;", b == ";;;;") or cmp(a, b)
...[';a;b;;', ';b;a;;', 'a;;;d;e', 'a;b;c;d;e', ';;;;']
Petr,
thank you for help and explanation.
It works
Lad
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,166
Messages
2,570,901
Members
47,442
Latest member
KevinLocki

Latest Threads

Top