python - 在整齐的列/表中打印列表列表

标签 python python-3.x list list-comprehension nested-lists

我有一个结构为 [[s: str, s: str, s: str]] 的列表列表,其中可以有任意数量的项目(列表)。

我想像这样在列中干净地打印它:

FirstFirst     FirstSecond    FirstThird
SecondFirst    SecondSecond   SecondThird
ThirdFirst     ThirdSecond    ThirdThird
foo            bar            foobar

因此,尽管长度不同,子列表中的每个项目在一列中都是左对齐的。

我已经尝试过非常复杂的列表推导式

lists = [['FirstFirst', 'FirstSecond', 'FirstThird'],
         ['SecondFirst', 'SecondSecond', 'SecondThird'],
         ['ThirdFirst', 'ThirdSecond', 'ThirdThird'],
         ['foo', 'bar', 'foobar']]

[print(f'{_[0]}{" " * (15 - len(_[0]))}{_[1]}{" " * (30 - len(_[0] + _[1] + " " * (15 - len(_[0]))))}{_[2]}') for _ in lists]

虽然这确实有效,但它非常暴力。

更糟糕的是,这个列表推导式完全不可扩展。如果我想向子列表中的每个项目添加另一个字符串,我将不得不向我的列表理解添加更多内容以使其仍然有效。此外,如果我希望两个列表具有不同的长度,一切都会被挫败。

执行此操作的更好方法是什么?

最佳答案

使用列表理解来解决副作用是一种糟糕的风格:你创建了一个完整的列表(这需要时间和内存),之后会被丢弃——使用简单的循环。

您需要计算每个单词的长度(在每一列中)。获取单词的最大长度很简单:

data = [['FirstFirst', 'FirstSecond', 'FirstThird'],
         ['SecondFirst', 'SecondSecond', 'SecondThird'],
         ['ThirdFirst', 'ThirdSecond', 'ThirdThird'],
         ['foo', 'verylongwordinsidehere', 'bar', ]]    # changed to a longer one


# get max word length
max_len = max(len(i) for j in data for i in j)

# do not use list comp for printing side effect - use a simple loop
for inner in data:
    for word in inner:
        print(f"{word:{max_len}}",end=" | ") # and format the length into it
    print()

得到

FirstFirst             | FirstSecond            | FirstThird             | 
SecondFirst            | SecondSecond           | SecondThird            | 
ThirdFirst             | ThirdSecond            | ThirdThird             | 
foo                    | verylongwordinsidehere | bar                    | 

这看起来有点丑,如果你只得到每列的最大长度恕我直言会更好:

# transpose the list, get the max of each column and store in as dict[column]=legnth
col_len = {i:max(map(len,inner)) for i,inner in enumerate(zip(*data))}

# print(col_len) # {0: 11, 1: 22, 2: 11}

# print using the column index from enumerate to lookup this columns lenght
for inner in data:
    for col,word in enumerate(inner):
        print(f"{word:{col_len[col]}}",end=" | ")
    print()

获得列宽调整后的输出:

FirstFirst  | FirstSecond            | FirstThird  | 
SecondFirst | SecondSecond           | SecondThird | 
ThirdFirst  | ThirdSecond            | ThirdThird  | 
foo         | verylongwordinsidehere | bar         | 


如果你需要让它更短,你可以使用' | '.join() 打印列表:

# do not use list comp for printing side effect - use a simple loop
for inner in data:
    print( ' | '.join( (f"{word:{max_len}}" for word in inner)))

如果你还需要打印不均匀的列表,zip() 不会做 - 你可以绕过它(研究 itertiols.zip_longest)但是如果你真的需要它,在你尝试了一些东西之后问一个新的数据问题做你需要它做的事。

关于python - 在整齐的列/表中打印列表列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61285626/

相关文章:

python - 在 Linux 上从 python 执行 makensis

python - 这个任务是什么? Python

list - 如何对结构列表中的数字求和? ( Racket )

python - 将表示列表的字符串转换为实际的列表对象

python - python/scipy/numpy 中的高效增量稀疏矩阵

python - 使用 main() 但没有将所有内容放入 def main() :? 是否正确

python - 如何使用 Python Flask-Security 使用 bcrypt 加密密码?

python - 如何仅在字符串的开头/结尾替换非字母数字字符?

python - Pandas 将数据写入单独的 csv 文件

python - 根据不同的索引位置删除列表列表中的公共(public)项