【问题标题】:Tab is skipping on certain iterations选项卡在某些迭代中跳过
【发布时间】:2021-01-14 11:58:45
【问题描述】:

我正在尝试打印列表列表并希望不同的列有一个选项卡。它适用于除第 3 行和第 5 行之外的所有行。不知道为什么!

import csv
FILENAME = "BaseballPlayers.csv"


#def display_lineup():

player_list = []
with open(FILENAME, newline="") as file:
    reader = csv.reader(file)
    for row in reader:
        player_list.append(row)
    
for i in range(len(player_list)):
    player = player_list[i]
    print(str(i+1) + ". " + player[0]+ "\t" + player[1]+ "\t" +player[2]+ "\t" +player[3])

输出:

【问题讨论】:

    标签: python list csv


    【解决方案1】:

    这不是标签被跳过的问题,而是标签工作方式的一个基本怪癖。跳格会将您带到下一个制表位,根据之前的情况,该位置可能并不总是相同。当您的播放器名称少于 5 个字符时,例如在“Tony”中,下一个制表位是“Tony”结束后的一个空格。

    如果我将代码中的输出复制到显示空白字符的文本编辑器中,它看起来是这样的:

    显然,标签在那里,但不是“足够大”

    一种解决方案是填充空格以将列值增加到最大列表,然后然后使用制表符。

    max_col_width = None
    player_list = []
    with open(FILENAME, newline="") as file:
        reader = csv.reader(file)
        for row in reader:
            if max_col_width is None:
                # This is the first row, set the lengths of each column as the max
                max_col_width = [len(c) for c in row]
            else:
                # For each column, the max is the larger of the 
                # existing max and the current column's length
                max_col_width = [max(m, len(c)) for m, c in zip(max_col_width, row)]
            player_list.append(row)
    

    zip 接受两个可迭代对象并同时对它们进行迭代,所以for m, c in zip(max_col_width, row) 和做的一样

    for i in len(row):
        m = max_col_width[i]
        c = row[i]
    

    如果我们打印max_col_width,我们可以看到值:[7, 2, 3, 3]。所以我们需要将第一列中的每个元素填充为 7 的长度,将第二列中的每个元素填充为 2 的长度,依此类推。 我们可以在打印之前使用str.ljust() 左对齐所有字符串:

    for i, player in enumerate(player_list):
        player = player_list[i]
        print(str(i+1) + ". " + player[0].ljust(max_col_width[0]) + "\t" + player[1].ljust(max_col_width[1]) + "\t" +player[2].ljust(max_col_width[2]) + "\t" +player[3].ljust(max_col_width[3]))
    

    或者上述更 Pythonic 的方式是使用生成器和 str.join() 以及 ljust

    for i, player in enumerate(player_list):
        player = player_list[i]
        print(str(i+1) + ". " + "\t".join(p.ljust(l) for p, l in zip(player, max_col_width)))
    

    现在我们有空格将每个名称的长度扩展到最大长度,并且制表符可以按照我们的意愿工作。

    作为文本,我们得到以下输出:

    1. Trevor   SS  588 173
    2. Garrett  2B  299 74 
    3. Tony     C   535 176
    4. Hunter   RF  580 182
    5. Ian      CF  443 113
    ...
    

    当然,既然您已经在填充内容,您可以完全消除 \t 字符并使用任意数量的空格(在下面的示例中为 4)来获得一致的列间距。

    for i, player in enumerate(player_list):
        player = player_list[i]
        print(str(i+1) + ". " + (" " * 4).join(p.ljust(l) for p, l in zip(player, max_col_width)))
        # Or alternatively, 
        # print(str(i+1) + ". " + "".join(p.ljust(l + 4) for p, l in zip(player, max_col_width)))
    

    【讨论】:

      猜你喜欢
      • 2018-05-25
      • 1970-01-01
      • 1970-01-01
      • 2015-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-11
      相关资源
      最近更新 更多