以整齐的列/表格打印列表列表

2024-05-12 02:26:01 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个结构为[[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]

虽然这确实有效,但这是非常残酷的

更糟糕的是,这个列表理解根本不可伸缩。如果我想在子列表中的每个项目中添加另一个字符串,我必须在列表理解中添加更多内容,以使所有内容仍然有效。另外,如果我想让两个列表具有不同的长度,那么所有内容都会失败

有什么更好的方法


Tags: 项目内容列表lenfoostrsecondfirstthirdthird
2条回答

使用理解:

# first map each string to formatted string with white space 
lists = [list(map(lambda item: f'{item:<20}', inner_list)) for inner_list in lists]
#then join them 
lists = [''.join(item) for item in lists]
print('\n'.join(lists))

这里唯一的问题是20不能是一个变量,它需要硬编码

使用列表理解来产生副作用是一种糟糕的风格:创建一个完整的列表(需要时间和内存),然后再扔掉——使用简单的循环

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

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                    | 

这看起来有点难看,如果您只获得每列的最大长度imho:

# 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_),但如果您确实需要,请在尝试完成需要的任务后,提出一个新问题,并提供相关数据

相关问题 更多 >