如何更改正在打印的列表的格式

How to change format of list in which it is being printed

我有一个列表:

import pokebase as pb
p1 = pb.pokemon('charmander')
for stat in p1.stats:
    result = ['''{}
{}'''.format(stat.stat.name, stat.base_stat)
        for stat in p1.stats]
print(f'''
{result[0]}
{result[1]}
{result[2]}
{result[3]}
{result[4]}
{result[5]}
''')

它像这样打印列表:

hp
39
attack
52
defense
43
special-attack
60
special-defense
50
speed
65

但我希望列表打印成这样:

hp                attack             defense    
39                52                 43 
special-attack    special-defense    speed        
60                50                 65

我该怎么做?
实际上我不知道 .format() 功能正常:(

左对齐 20 个字符 space

如果您需要右对齐,请使用 >20

你可以忽略那里的numpy工程。我这样做是为了方便。但主要思想是使用 <20 左格式

result = ['hp','39','attack','52','defense','43','special-attack','60','special-defense','50','speed','65']
# for convenience to not complicate code for explanation
r = np.array(result)
r.shape = (2, 3, 2)
# array([[['hp', '39'],
#         ['attack', '52'],
#         ['defense', '43']],

#        [['special-attack', '60'],
#         ['special-defense', '50'],
#         ['speed', '65']]], dtype='<U15')


row_format ="{:<20}" * 3
for row in r:
    # here row1 is column of [hp, attack defense], look above comment for visualization
    row1 = row[:, 0]
    # row2 is column of values
    row2 = row[:, 1]
    # *row1 is unwrapping list row1 into arguments for format function
    print(row_format.format(*row1))
    print(row_format.format(*row2))
hp                  attack              defense             
39                  52                  43                  
special-attack      special-defense     speed               
60                  50                  65           

有很多方法可以解决这个问题。这是一种方法:-

import pokebase as pb
p1 = pb.pokemon('charmander')
R = []
mlen = 0
pad = 2
for v in p1.stats:
    n = v.stat.name
    mlen = max(mlen, len(n) + pad)
    R.append((n, v.base_stat))
t = 0
for i in range(len(R) * 2):
    if i != 0 and i % 3 == 0:
        t ^= 1
        print()
    print(f'{R[i//2][t]: <{mlen}}', end='')
print()

直接使用 result 中的数据,您只需在右侧填充空格以强制列对齐。

result = [
    'hp', '39', 
    'attack', '52', 
    'defense', '43', 
    'special-attack', '60', 
    'special-defense', '50', 
    'speed', '65'
]
stat_line = ''
val_line = ''
for i, (stat, value) in enumerate(zip(result[::2], result[1::2]), 1):
    if i % 3:
        stat_line += f'{stat:<20}'
        val_line += f'{value:<20}'
    else:
        print(stat_line + stat)
        print(val_line, value)
        stat_line = ''
        val_line = ''

正在发生的事情的分解:

[::2] 分割您的 list 并遍历所有其他字符。

[1::2] 除了它从第二个元素开始之外做同样的事情。

zip() 允许您一次迭代 2 个可迭代对象。如此有效,您将获得 ('hp', 39)('attack', 52) 等。在迭代时解压缩到 (stat, value)

enumerate(iterable, 1) 在迭代时为您提供从 1 开始递增的整数。您可以使用它来确定您何时处于第三个元素。(i % 3)这用于 print 当前 3 个统计数据和值并清除字符串,以便您可以继续添加它们。

从那里开始,它只是简单地使用 f'{stat:<20}' 在字符串值上右填充 20 个空格以强制它们都具有相同的长度并因此对齐。

最终结果:

hp                  attack              defense
39                  52                   43
special-attack      special-defense     speed
60                  50                   65

试试这个:

def print_in_my_way(x):
    global result
    m = max(result, key=lambda x: len(str(x)))
    m = len(str(m)) 
    # m += 5 If u need more space 
    def do(subx):
        print(*[f'{i:<{m}}' for i in subx])
    do(x[::2])
    do(x[1::2])

result = ['hp',
39,
'attack',
52,
'defense',
43,
'special-attack',
60,
'special-defense',
50,
'speed',
65]
n = len(result)//2
print_in_my_way(result[:n])
print_in_my_way(result[n:])

使用 n 的值,您可以调整第一行需要多少个值等等!