Reputation: 45
I have text file with parse logged file, file contains: file: output.log End result should be: 1. sorted the list with max number
rt01,te1/1,111,11
rt02,te1/1,11,10
rt01,te1/2,122,20
rt02,te1/2,113,5
rt02,te1/3,10,1
rt03,te1/1,1,6
rt03,te1/2,11,8
Result:
rt01,te1/2,122,20
rt01,te1/1,111,11
rt02,te1/1,11,10
rt03,te1/2,11,8
rt03,te1/1,1,6
rt02,te1/2,113,5
rt02,te1/3,10,1
What is the best way, to get the max value within the list:
I try:
results = []
top = []
bottom = []
found = 0
with open('Python/output.log', 'r') as f:
for line in f:
line = line.split(",")
results.append(line)
print results
for i,j in enumerate(results[:-1]):
#print results[i+1][3]
if j[3] > results[i+1][3]:
top.append(j)
elif results[i+1][3] > top[3]:
bottom.append(results[i+1])
if top[i-1][3] > results[i+1][3]:
top.append(j.pop())
bottom.append(j)
#top.append(j[])
print(top)
print(bottom)
Upvotes: 0
Views: 71
Reputation: 104102
This is a variant of a natural sort. If you are ONLY grouping by the final number in a CSV line, you can split on the ','
, convert that to an int
and then negate to get max->min sorting:
s='''\
rt01,te1/1,111,11
rt02,te1/1,11,10
rt01,te1/2,122,20
rt02,te1/2,113,5
rt02,te1/3,10,1
rt03,te1/1,1,6
rt03,te1/2,11,8'''
print '\n'.join(sorted(s.splitlines(), key=lambda s: -int(s.split(',')[-1])))
Prints:
rt01,te1/2,122,20
rt01,te1/1,111,11
rt02,te1/1,11,10
rt03,te1/2,11,8
rt03,te1/1,1,6
rt02,te1/2,113,5
rt02,te1/3,10,1
Since Python uses a stable sort, the groups in the first columns will remain in file order unless sorted by the final column.
If you want to sort BOTH by the final column and the numeral in the first column, you can use a regex and do something like:
import re
def f(line):
digits=map(int, re.findall(r'\d+', line))
return digits[0], -digits[-1]
print '\n'.join(sorted(s.splitlines(), key=f))
Prints:
rt01,te1/2,122,20
rt01,te1/1,111,11
rt02,te1/1,11,10
rt02,te1/2,113,5
rt02,te1/3,10,1
rt03,te1/2,11,8
rt03,te1/1,1,6
Or, if you want to sort primarily by the final column but group by the first column you can reverse the order of the tuple returned by f
:
def f(line):
digits=map(int, re.findall(r'\d+', line))
return -digits[-1], digits[0]
print '\n'.join(sorted(s.splitlines(), key=f))
Upvotes: 0
Reputation: 4460
My own solution, similar to @chrisz with sorted()
but using the csv
library
import csv
results = []
with open('Python/output.log', 'r') as f:
csvreader = csv.reader(f)
for line in csvreader:
results.append(line)
sorted_results = sorted(results, key=lambda x: int(x[3]), reverse=True)
Outputs:
[['rt01', 'te1/2', '122', '20'],
['rt01', 'te1/1', '111', '11'],
['rt02', 'te1/1', '11', '10'],
['rt03', 'te1/2', '11', '8'],
['rt03', 'te1/1', '1', '6'],
['rt02', 'te1/2', '113', '5'],
['rt02', 'te1/3', '10', '1']]
Upvotes: 0
Reputation: 51185
You can use the last number in each line as the key to sorted()
:
with open('test.txt') as f:
data = f.read().splitlines()
data = sorted(data, key= lambda x: int(x.split(',')[-1]), reverse=True)
print('\n'.join(data))
Output:
rt01,te1/2,122,20
rt01,te1/1,111,11
rt02,te1/1,11,10
rt03,te1/2,11,8
rt03,te1/1,1,6
rt02,te1/2,113,5
rt02,te1/3,10,1
Upvotes: 1