以表格形式打印字典列表

时间:2016-10-15 08:18:12

标签: python

假设我将此列表作为全局列表

 dataset =[{'Major': 'Biology', 'GPA': '2.4', 'Name': 'Edward'},
           {'Major': 'Physics', 'GPA': '2.9', 'Name':'Emily'},  
           {'Major':'Mathematics', 'GPA': '3.5', 'Name': 'Sarah'}]

并想要一个函数print()将其打印为

 name     major        GPA 
 =============================== 
 edward   Biology      2.4 
 Emily    physics      2.9 
 sarah    mathematics  3.5

5 个答案:

答案 0 :(得分:6)

您可以使用模块tabulate。 以下代码与python 2兼容,对于python 3,请参阅注释。

>>> import tabulate
>>> dataset =[{'Major': 'Biology', 'GPA': '2.4', 'Name': 'Edward'}, {'Major': 'Physics', 'GPA': '2.9', 'Name': 'Emily'}, {'Major': 'Mathematics', 'GPA': '3.5', 'Name': 'Sarah'}]
>>> header = dataset[0].keys()
>>> rows =  [x.values() for x in dataset]
>>> print tabulate.tabulate(rows, header)
Major          GPA  Name
-----------  -----  ------
Biology        2.4  Edward
Physics        2.9  Emily
Mathematics    3.5  Sarah

您可以将tablefmt参数用于不同的表格格式

>>> print tabulate.tabulate(rows, header, tablefmt='grid')
+-------------+-------+--------+
| Major       |   GPA | Name   |
+=============+=======+========+
| Biology     |   2.4 | Edward |
+-------------+-------+--------+
| Physics     |   2.9 | Emily  |
+-------------+-------+--------+
| Mathematics |   3.5 | Sarah  |
+-------------+-------+--------+
>>> print tabulate.tabulate(rows, header, tablefmt='rst')
===========  =====  ======
Major          GPA  Name
===========  =====  ======
Biology        2.4  Edward
Physics        2.9  Emily
Mathematics    3.5  Sarah
===========  =====  ======

答案 1 :(得分:2)

for dicts in dataset:
    print(dicts.get('Name')),
    print(dicts.get('Major')),
    print(dicts.get('GPA')),

示例

>>> dataset =[{'Major': 'Biology', 'GPA': '2.4', 'Name': 'Edward'}, {'Major': 'Physics', 'GPA': '2.9', 'Name': 'Emily'}, {'Major': 'Mathematics', 'GPA': '3.5', 'Name': 'Sarah'}]
>>> 
>>> for dicts in dataset:
...         print(dicts.get('Name')),
...         print(dicts.get('Major')),
...         print(dicts.get('GPA')),
... 
Edward Biology 2.4 Emily Physics 2.9 Sarah Mathematics 3.5

答案 2 :(得分:1)

这个怎么样:

from __future__ import print_function

dataset =[{'Major': 'Biology', 'GPA': '2.4', 'Name': 'Edward'},Physics', 'GPA': '2.9', 'Name': 'Emily'},Mathematics', 'GPA': '3.5', 'Name': 'Sarah'}]

[print("%s %s: %s\n"%(item['Name'],item['Major'],item['GPA'])) for item in dataset]

结果:

Edward Biology: 2.4

Emily Physics: 2.9

Sarah Mathematics: 3.5

答案 3 :(得分:0)

对于矩阵格式的结构化输出,我会这样做:

dataset =[{'Name': 'Edward', 'Major': 'Biology',     'GPA': '2.4'},
          {'Name': 'Emily',  'Major': 'Physics',     'GPA': '2.9'},
          {'Name': 'Sarah',  'Major': 'Mathematics', 'GPA': '3.5'}]
​
keys = []
vals = []
for data in dataset:
    val = []
    for k,v in data.items():
        keys.append(k)
        val.append(v)
    vals.append(val)
​
print(list(dict.fromkeys(keys)))
for v in vals:
    print(v)

['Name', 'Major', 'GPA']
['Edward', 'Biology', '2.4']
['Emily', 'Physics', '2.9']
['Sarah', 'Mathematics', '3.5']

这样,如果您愿意,也可以使用pandas:

import pandas as pd

dataset =[{'Name': 'Edward', 'Major': 'Biology',     'GPA': '2.4'},
          {'Name': 'Emily',  'Major': 'Physics',     'GPA': '2.9'},
          {'Name': 'Sarah',  'Major': 'Mathematics', 'GPA': '3.5'}]

keys = []
vals = []
for data in dataset:
    val = []
    for k,v in data.items():
        keys.append(k)
        val.append(v)
    vals.append(val)

pd.DataFrame([v for v in vals], columns=list(dict.fromkeys(keys)))

    Name    Major       GPA
0   Edward  Biology     2.4
1   Emily   Physics     2.9
2   Sarah   Mathematics 3.5

当然,pandas有更简单的方法:

import pandas as pd

dataset =[{'Name': 'Edward', 'Major': 'Biology',     'GPA': '2.4'},
          {'Name': 'Emily',  'Major': 'Physics',     'GPA': '2.9'},
          {'Name': 'Sarah',  'Major': 'Mathematics', 'GPA': '3.5'}]

pd.DataFrame(dataset).reindex(columns=['Name','Major','GPA'])

    Name    Major       GPA
0   Edward  Biology     2.4
1   Emily   Physics     2.9
2   Sarah   Mathematics 3.5

答案 4 :(得分:0)

我对tabulate &co的行为感到不满,我为dicts编写了一个文档化,高性能的辅助函数。 timeit:<1毫秒,列表格式的21毫秒为纯格式。

它具有自定义转换器,格式设置,列排除和值替换的多功能功能。自从它的插件以来就非常快:最小的MWE是
print(tabulate_dict([{'col1':'v1'}, {'col1':'v2'}]))

col1
----
v1
v2
def tabulate_dict(dicts: List[Dict], keys: List[str] = None, pads: List[str] = None, fcodes: List[str] = None,
                  convert_headers: Dict[str, Callable] = None, header_names: List[str] = None,
                  skip_none_lines: bool = False, replace_values: Dict[str, Any] = None):
    """ Generate ascii table from dictionary
    dicts: input dictionary list; empty lists make keys OR header_names mandatory
    keys: order list of keys to generate columns for; no key/dict-key should suffix with '____' else adjust code-suffix
    pads: indicate padding direction and size, eg <10 to right pad alias left-align
    fcodes: formating codes for respective column type, eg .3f
    convert_headers: apply converters(dict) on column keys k, eg timestamps
    header_names: supply for custom column headers instead of keys
    skip_none_lines: skip line if contains None
    replace_values: specify per column keys k a map from seen value to new value;
                    new value must comply with the columns fcode; CAUTION: modifies input (due speed)
    """
    # optional arg prelude
    if keys is None:
        if len(dicts) > 0:
            keys = dicts[0].keys()
        elif header_names is not None:
            keys = header_names
        else:
            raise ValueError('keys or header_names mandatory on empty input list')
    if pads is None:
        pads = [''] * len(keys)
    elif len(pads) != len(keys):
        raise ValueError(f'bad pad length {len(pads)}, expected: {len(keys)}')
    if fcodes is None:
        fcodes = [''] * len(keys)
    elif len(fcodes) != len(fcodes):
        raise ValueError(f'bad fcodes length {len(fcodes)}, expected: {len(keys)}')
    if convert_headers is None:
        convert_headers = {}
    if header_names is None:
        header_names = keys
    if replace_values is None:
        replace_values = {}
    # build header
    headline = '│'.join(f"{v:{pad}}" for v, pad in zip_longest(header_names, pads))
    underline = '─' * len(headline)
    # suffix special keys to apply converters to later on
    marked_keys = [h + '____' if h in convert_headers else h for h in keys]
    marked_values = {}
    s = '│'.join(f"{{{h}:{pad}{fcode}}}" for h, pad, fcode in zip_longest(marked_keys, pads, fcodes))
    lines = [headline, underline, ]
    for d in dicts:
        none_keys = [k for k, v in d.items() if v is None]
        if skip_none_lines and none_keys:
            continue
        elif replace_values:
            for k in d.keys():
                if k in replace_values and d[k] in replace_values[k]:
                    d[k] = replace_values[k][d[k]]
                if d[k] is None:
                    raise ValueError(f"bad or no mapping for key '{k}' is None. Use skip or change replace mapping.")
        elif none_keys:
            raise ValueError(f'keys {none_keys} are None in {d}. Do skip or use replace mapping.')
        for h in convert_headers:
            if h in keys:
                converter = convert_headers[h]
                marked_values[h + '____'] = converter(d)
        line = s.format(**d, **marked_values)
        lines.append(line)
    return '\n'.join(lines)

计算列? np: print(tabulate_dict([{'col1':1}, {'col1':2}], keys=['col1', 'comp1'], pads=['<5', '>4'],convert_headers={'comp1': lambda d: d['col1']+1}))
输出是

col1 │comp1
───────────
1    │   2
2    │   3