2017-04-01 15 views
2

假设我们有以下方式在文件中的很多记录。Pythonic的方式来排序多列记录

10.10.10.10(tcp/443) : Some SSL Vulnerability : Medium : Patched

10.10.10.11(tcp/888) : Some RCE Vulnerability : High : Not Patched

这些记录与价值观Critical, High, Medium, Low第3列。

什么是以这种方式排序这些记录的最佳pythonic方法: 1.关键,2.High,3.Medium 4. Low?

+1

如何[枚举](https://docs.python.org/3/library/enum.html)?更具体地说,[IntEnum](https://docs.python.org/3/library/enum.html#intenum)。 –

+0

我们可以假设您知道如何将数据读入列表并将排序后的列表数据写回到文件中?你应该发布[mcve],表明你试图解决这个问题。你想要一个纯粹的Python解决方案吗?或者你想使用熊猫? –

回答

1

这里是一个纯Python的解决方案,使用字典的Critical, High, Medium, Low字符串转换为它们的数值;该数值用作list.sort的排序键函数参数。我的关键功能还使用每个记录的第一个字段作为辅助排序键,以便在按等级排序的每个部分中,条目也按该第一个字段排序。

由于您的问题只包含2行样本数据,我构建了一些简单的假数据。

data = '''\ 
00 : abc : Low 
01 : def : High 
02 : ghi : Low 
03 : jkl : Medium 
04 : mno : High 
05 : pqr : Medium 
06 : stu : High 
07 : vwx : Medium 
08 : yza : High 
09 : bcd : High 
10 : efg : High 
11 : hij : Critical 
12 : klm : Critical 
13 : nop : Medium 
14 : qrs : High 
15 : tuv : Critical 
'''.splitlines() 
data = [row.split(' : ') for row in data] 

grades = {'Critical': 1, 'High': 2, 'Medium': 3, 'Low': 4} 

data.sort(key=lambda t: (grades[t[2]], t[0])) 
for row in data: 
    print(' : '.join(row)) 

输出

11 : hij : Critical 
12 : klm : Critical 
15 : tuv : Critical 
01 : def : High 
04 : mno : High 
06 : stu : High 
08 : yza : High 
09 : bcd : High 
10 : efg : High 
14 : qrs : High 
03 : jkl : Medium 
05 : pqr : Medium 
07 : vwx : Medium 
13 : nop : Medium 
00 : abc : Low 
02 : ghi : Low 
1

如果你可以改变你的表成大熊猫的数据帧(例如,使用pandas.read_csv),那么这将做的工作:

import pandas as pd 
df=pd.DataFrame({'a':[1,2,3,4,5,6],'b':['a','b','c','d','e','f'],'val':['critical','high','low','medium','critical','low']}) 
df['val'] = pd.Categorical(df['val'],['critical','high','medium','low']) 
df.sort_values(by='val',inplace=True) 

然后在开始df

a b val 
0 1 a critical 
1 2 b high 
2 3 c low 
3 4 d medium 
4 5 e critical 
5 6 f low 

并且最后df

a b val 
0 1 a critical 
4 5 e critical 
1 2 b high 
3 4 d medium 
2 3 c low 
5 6 f low 

I上述N的代码,即指定的顺序线是使用IntEnum对于字典的列表

df['val'] = pd.Categorical(df['val'],['critical','high','medium','low']) 
2

实施例。

from enum import IntEnum 
class Vulnerability(IntEnum): 
    CRITICAL = 1 
    HIGH = 2 
    MEDIUM = 3 
    LOW = 4 

records = [] 
records.append({'v': Vulnerability.MEDIUM}) 
records.append({'v': Vulnerability.HIGH}) 
records.append({'v': Vulnerability.CRITICAL}) 
records.append({'v': Vulnerability.LOW}) 

print(records) 
# [{'v': <Vulnerability.MEDIUM: 3>}, {'v': <Vulnerability.HIGH: 2>}, {'v': <Vulnerability.CRITICAL: 1>}, {'v': <Vulnerability.LOW: 4>}] 

print(records[0]['v'] < records[1]['v']) 
# False 

print(sorted(records, key = lambda k: k['v'])) 
# [{'v': <Vulnerability.CRITICAL: 1>}, {'v': <Vulnerability.HIGH: 2>}, {'v': <Vulnerability.MEDIUM: 3>}, {'v': <Vulnerability.LOW: 4>}] 
相关问题