table 的 Pythonic 解析?

Pythonic parsing of table?

我有一个像这样的 table,它会变大变小: 它当然包括制表符、新行等等。它是一个字符串。

Interface        group           vlan    ver                                                          
fa1/6            239.0.0.3       2       2                                                            
fa1/2            239.0.0.1       1       2     
fa1/1            239.0.0.0       3       2
fa1/6            239.0.0.1       1       2

我想解析成

格式
vlan  ports
----  -----
   1  fa1/2, fa1/6  
   2  fa1/6
   3  fa1/1

但是我这样做的方式很乱,我觉得进行的字符串操作比我需要的要多得多,拆分,排序等等。你们会用什么方法?

尝试 pandas:

import pandas as pd
from StringIO import StringIO

s = """Interface        group           vlan    ver                                                          
fa1/6            239.0.0.3       2       2                                                            
fa1/2            239.0.0.1       1       2     
fa1/1            239.0.0.0       3       2
fa1/6            239.0.0.1       1       2"""
header = "vlan    ports\n----    -----\n"

现在您可以:

>>> df = pd.read_csv(StringIO(s), delim_whitespace=True)\
           .groupby('vlan')['Interface']\
           .apply(lambda x: ', '.join(x))
>>> print(header + df.to_string())
vlan    ports
----    -----
1       fa1/2, fa1/6
2              fa1/6
3              fa1/1

三步法:

  1. 将文本行转换为字典数组
  2. 遍历字典数组以将您要创建另一个字典的信息组合在一起。
  3. 将生成的字典打印为 table。

示例:

foo="""Interface        group           vlan    ver  
fa1/6            239.0.0.3       2       2
fa1/2            239.0.0.1       1       2
fa1/1            239.0.0.0       3       2
fa1/6            239.0.0.1       1       2
"""

def parse_lines(lines):
  headers = lines[0].split()
  entries = []
  for r in lines[1:]:
    if not len(r): continue    # skip blank lines
    vals = r.split()
    e = dict(zip(headers,vals))
    entries.append(e)
  return entries

def doit():
  entries = parse_lines(foo.split("\n"))
  ports = {}
  for e in entries:
    vlan = e["vlan"]
    if not (vlan in ports): ports[vlan] = []
    ports[vlan].append( e["Interface"] )
  print "%6s %s" % ("vlan", "ports")
  for vlan in ports:
    print "%6s %s" % (vlan, ', '.join(ports[vlan]))

doit()