开发者

Sorting by compare values in Python

Newbie in Python need help!

I have a file with a structure:

[timestamp] [level] [source] message

which contains following lines(for example):

[Wed Oct 11 14:34:52 2000] [error] [client 127.0.0.1] error message
[Wed Oct 11 18:56:52 2000] [warning] [client 127.0.0.1] error message
[Wed Oct 11 22:15:52 2000] [critical] [client 127.0.0.1] error message

And i need to sort this lines by [level] and display a result in STDOUT. But there is two condi开发者_JAVA百科tions: we must have opportunity to select [level] name which uses to sorting and all lines with upper [level] should be displayed too.

[level] values:
critical = 50
error = 40
warning = 30
info = 20
debug = 10

I decide to do this with suits:

suits = {'critical': 50, 'error': 40, 'warning': 30}
l = ['critical','error','warning']
print sorted(l, key=suits.get)

But i suppose it's not the best way.

I hope you'll help me to solve this...


I would divide this into two parts:

1) Write a function that, given a line of the file, returns the level number. Call this level_number for part 2.

2) Use that function with the key parameter in your chosen sort call:

with open(fname) as f:
  sorted_lines = sorted(f, key=level_number)

The function for 1) can be created with split or a regular expression.


Here is working code (I couldn't help, even though @Hamidi said "We won't write your program for you" ;)

import re

PAT = re.compile(r'\[(?P<time>[^\]]+)\] \[(?P<level>[^\]]+)\] \[(?P<client>[^\]]+)\] (?P<message>\S+)')
LEVELS = ['critical', 'error', 'warning', 'info', 'debug']

def level_number(line):
    match = PAT.match(line)
    if match:
        level = PAT.match(line).groupdict()['level']
        return LEVELS.index(level)
    return len(LEVELS)

with open('log.txt') as f:
    result = sorted(f, key=level_number)

Note, I included the regex with groups for each part (this may come in convenience for further processing). HTH.


Quick one-liner to give you some idea to get the key from the text line:

{'critical': 50, 'error': 40, 'warning': 30, 'info': 20, 'debug': 10}.get(line.split('] [')[1].lower(), 0)

Do not use this in production code, remember, "readability counts"

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜