【问题标题】:Printing a dict of lists as a grid-layout将列表的字典打印为网格布局
【发布时间】:2017-07-12 06:03:03
【问题描述】:

好的,我以前读过所有这些,我认为 pandas 可能是一个解决方案,但我的问题略有不同:
Print a dictionary of lists vertically
Printing Lists as Tabular Data
print dictionary values which are inside a list in python
@987654324 @

我有一个列表的字典:

dict={"A":[i1, i2,i3], "B":[i1, i4,i5], "C":[i1, i2,i5]}

我想要的输出是:

    i1    i2    i3    i4    i5   
A    x     x     x     -     -   
B    x     -     -     x     x   
C    x     x     -     -     x  

(甚至更好,

    i1    i2    i3    i4    i5  
A    A     A     A     -     -  
B    B     -     -     B     B  
C    C     C     -     -     C  

或匹配另一个字典中的 A、B、C 或 (A,in) 的值, 但如果我只能拥有第一张桌子,我会非常高兴)

没有列表包含重复,但这些列表中的每个元素都是从同一个列表中提取的(实际上我的问题是用相应的蛋白质制作一个带注释的术语网格,键是注释的术语,它们是与这些蛋白质相关的功能在我的研究背景下)。

我确实可以想到一种复杂的方法(构建 0 和 1 的向量以将每个列表与一般列表进行比较,将这些向量与键相关联,将其放入 pandas DataFrame 中,该数据框将由我的魔力是重新建立每个列表的大量实体,然后打印出来),但这似乎/很乏味/不符合 Python 标准。

我认为必须有一种已知的方法来使用某些模块(pandas、prettytable 或其他?);我只是不知道。 因此,我很高兴对此有任何见解。谢谢

【问题讨论】:

    标签: python pandas dictionary grid-layout pretty-print


    【解决方案1】:

    applylambda

    d = {
        "A": ['i1', 'i2', 'i3'],
        "B": ['i1', 'i4', 'i5'],
        "C": ['i1', 'i2', 'i5']
    }
    
    df = pd.DataFrame(d)
    
    df.apply(lambda c: pd.Series(c.name, c.values)).fillna('-').T
    
      i1 i2 i3 i4 i5
    A  A  A  A  -  -
    B  B  -  -  B  B
    C  C  C  -  -  C
    

    【讨论】:

    • 太棒了。谢谢。我想我总是对 pandas 将 dicts 中的列表转换为列的方式感到不安。如果我理解得很好,我只需要获取 c.values 而不是 c.name 来获取值吗?太好了。
    【解决方案2】:

    只是一个简单的草稿(基于大量str.format):

    def create_table(dictionary, columns):
        column_set = set(columns)  # only to speed up "in" calls, could be omitted
        # Fill in the symbols depending on the presence of the corresponding columns
        filled_dct = {key: [' X' if col in lst else ' -' for col in column_set] 
                      for key, lst in dct.items()}
    
        # A template string that is filled for each row
        row_template = '   '.join(['{}']*(len(columns)+1))
    
        print(row_template.format(*([' '] + columns)))
        for rowname, rowcontent in sorted(filled_dct.items()):
            print(row_template.format(*([rowname] + rowcontent)))
    
    dct = {"A": ['i1', 'i2', 'i3'], 
           "B": ['i1', 'i4', 'i5'], 
           "C": ['i1', 'i2', 'i5']}
    
    columns = ['i1', 'i2', 'i3', 'i4', 'i5']
    
    create_table(dct, columns)
        i1   i2   i3   i4   i5
    A    X    X    -    -    X
    B    X    -    X    X    -
    C    X    X    X    -    -
    

    虽然它不是很灵活(可变列宽等),但应该很容易扩展。

    【讨论】:

    • 感谢您的回答。这就是我对“复杂方式”的看法(诚然,它并没有我想象的那么复杂,但这并不是真正的 python 方式来做我想做的事。我会为你的努力投票)跨度>
    【解决方案3】:

    考虑您的输入字典:

    dic = {"A":["i1", "i2", "i3"], "B":["i1", "i4", "i5"], "C":["i1", "i2", "i5"]}
    

    使用dict.fromkeys(),以便可迭代成为dic(又名dic.values())中存在的值,这是一个list,它的默认值是dic's键(又名dic.keys())。

    字典理解的帮助下,最后一步计算的结果将构成数据框的值。转置它,使列标题成为索引轴,反之亦然。

    稍后,用"-" 填写Nans

    pd.DataFrame({k:dict.fromkeys(v,k) for k,v in dic.items()}).T.fillna("-")
    #                               ^----- replace k with "x" to get back the first o/p
    

    【讨论】:

    • 很好的答案,非常pythonic和聪明。我不会选择它作为接受的答案,因为创建 dicts 的过程在概念上处理起来稍微复杂一些。但我保留了对它的熟练使用来告诉熊猫如何处理列和行......
    猜你喜欢
    • 2019-09-19
    • 2015-05-29
    • 2020-06-14
    • 2019-03-31
    • 1970-01-01
    • 1970-01-01
    • 2015-10-03
    • 1970-01-01
    • 2021-09-27
    相关资源
    最近更新 更多