【问题标题】:How to print two aligned columns of text from a list (which may have an odd number of elements) in python?如何在python中从列表(可能有奇数个元素)中打印两个对齐的文本列?
【发布时间】:2021-11-10 04:12:07
【问题描述】:

我有一些代码从用户那里获取输入并将其存储在一个列表中。该列表可能有奇数或偶数个元素,例如: my_list = ['Beef','Chicken','Eggs','Lamb','Nuts','Pork'](偶数个元素)

my_list = ['Beef','Chicken','Eggs','Lamb','Nuts','Pork','Potatoes'](奇数个元素)

我想将my_list 存储在一个字符串变量中,这样当我print(var) 或创建一个tkinter 消息框时,我的程序将输出如下两列:

-- Beef       --Chicken
-- Eggs       --Lamb
-- Nuts       --Pork
-- Potatoes

我知道如何操作字符串,但我一直坚持创建列。我试过这个:

for x,y in zip(my_list[0::2], my_list[1::2]):
    print("{0} {1}".format(x, y))

但这不适用于奇数长度的列表。 我也尝试过更复杂的:

#When my_list = ['Beef','Chicken','Eggs','Lamb','Nuts','Pork','Potatoes']
list1 = []
list2 = []
while len(my_list) != 0:
        list1.append(my_list[0])
        my_list.pop(0)
        if len(my_list) == 0:
            list2.append('')
        else:
            list2.append(my_list[0])
            my_list.pop(0)
    for i in range (len(list1)):
        blank_space = 40 - len(list1[i-1])
        string2 = "\n--" + list1[i] + ' '*blank_space + '--' + list2[i]
        string1 = string1 + string2
    print(string1)

但我得到的输出是这样的:

--Beef                                --Chicken
--Eggs                                    --Lamb
--Nuts                                    --Pork
--Potatoes                                    --

没有正确对齐列。

除了将其拆分为列之外,输出格式也很重要:

--Element1    --Element2
--Element3    --Element4

而不是任何其他形式。对于我犯错的地方,我真的很感激任何帮助。如果您需要更多说明,请告诉我,我会将其添加到我的问题中。

编辑: 该函数必须适用于所有这些列表:

my_list = ['Beef','Chicken','Eggs','Lamb','Nuts','Pork']
my_list = ['Beef','Chicken','Eggs','Lamb','Nuts','Pork','Potatoes']
my_list = ['Beef','Chicken','Eggs','Lamb','Nuts','Pork','Potatoes','Dairy']
my_list = ['Australian Beef','Chicken','Eggs','Lamb','Nuts','Pork','Potatoes','Dairy']

第二次编辑 我终于意识到为什么有时它不对齐。空格数是正确的,所以你所有的答案都是正确的。不幸的是,因为有些字母比其他字母更薄,所以列不会很好地对齐(至少在 Python IDLE 和 Tkinter 中)。例如,iiii 比 Python 中的 mmmm 短。有没有办法解决这个问题?

【问题讨论】:

  • "但这不适用于奇数长度的列表。"你能想出一种方法来提前判断列表的长度是否为奇数吗?如果检测到这种情况,能不能想办法分开处理? (提示:如果您只是删除列表的最后一个元素会发生什么?如果您将您的技术用于该结果列表,您能想出一种简单的方法来修复该输出吗?)
  • "未正确对齐列" 当您计算blank_space 数量时,您使用list1 的哪个元素?同时通过循环,list1 的哪个元素你用对应数量的blank_space 填充?你明白为什么这会导致问题吗?
  • 顺便说一句,您应该尝试research 了解 Python 中的字符串格式。内置了强大的工具,这意味着您不必自己计算空间量。
  • 感谢您回复@KarlKnechtel,我可以检测列表是奇数还是偶数,但我无法删除任何元素。我也意识到我在一行中使用i 而在另一行中使用i+1 的问题,感谢您指出这一点!不幸的是,在我修复它之后它仍然无法正常工作。我对字符串格式进行了研究,但无法成功应用它
  • "但我无法删除任何元素。"你不知道如何在 Python 中从列表中删除一个元素?如果您尝试使用搜索引擎来解决这个问题呢? “我对字符串格式进行了研究,但无法成功应用它”如果您向我们展示它,我们只能帮助您尝试(现在可能作为一个不同的问题,使用专注于该特定任务的代码)。跨度>

标签: python python-3.x list multiple-columns


【解决方案1】:

我试图把它放在评论中,但它太长了,所以它变成了它自己的答案。为了扩展其他答案,我认为解释代码在做什么是个好主意。

将代码分成几部分,从 j1-lee 的回答开始,我们有:

for i in range(0, len(my_list), 2):
    print(' '.join(f"-- {s:10}" for s in my_list[i:i+2]))

output = '\n'.join(' '.join(f"-- {s:10}" for s in my_list[i:i+2]) for i in range(0, len(my_list), 2))

有几个部分:

  • f-strings 是格式化字符串的便捷方式。引号前的f 表示一个 f 字符串。
  • 在 f 字符串中有一个变量 s,它是列表理解 for s in my_list[i:i+2] 的一部分。 {s:10} 表示字符串的长度为10。 (或者你可以像 Bharel 所做的那样,使用另一个与最长字符串的长度相关的变量,并使用它而不是 10。)如果你打算将它应用于不同的列表,这可能是一个好主意。李>
  • (f"-- {s:10}" for s in my_list[i:i+2]) 创建一个生成器,例如,如果您写了x = (f"-- {s:10}" for s in my_list[0:0+2]),然后尝试for i in x: print(i),您的输出将是两个字符串:-- Beef-- Chicken
  • ' '.join(...) 将它们连接到一个列表中,就像 j1-lee 所说,如果您将它们嵌套在多个列表推导中,则可以得到一行。

我认为通过将 j1-lee 和 Bharel 的做法结合起来,您可能会获得最多功能。请注意,我删除了 join 命令中的空格,因为现在有一个变量定义了列之间的空格。

def generate_columns(list_in, n_columns, column_space, output_as_list = True):
    # Figure our the length of the longest word in the list
    longest_word_length = max(map(len,list_in))
    column_length = longest_word_length + column_space

    output = [''.join([f"-- {s:{column_length}}" \
                       for s in my_list[i:i+n_columns]]) for i in range(0, len(my_list), n_columns)]
    if output_as_list:
        return output
    return '\n'.join(o for o in output)


my_list = ['Beef','Chicken','Eggs','Lamb','Nuts','Pork','Potatoes']

print(generate_columns(my_list, 3, 5))
#['-- Beef         -- Chicken      -- Eggs         ', '-- Lamb         -- Nuts      -- Pork         ', '-- Potatoes     ']
print(generate_columns(my_list, 2, 3, output_as_list = False))
#-- Beef       -- Chicken
#-- Eggs       -- Lamb
#-- Nuts       -- Pork
#-- Potatoes

【讨论】:

  • 感谢您的额外解释。不幸的是,当我将另一个元素包含到my_list 中时,我遇到了另一个问题,如下所示:my_list = ['Beef','Chicken','Eggs','Lamb','Nuts','Pork','Potatoes','Dairy']。当我将该列表运行到您的函数中时,“乳制品”没有正确对齐,我不知道为什么。
  • 我添加了更多关于我将不得不在我的问题中处理的列表类型的信息。
  • 如果提供的答案是正确的,如您所说,那么我认为将它们标记为这样是公平的。在我看来,您对问题的理解已经发展(这是学习的正常部分),实际上它已成为理解 tkinter 中不同字体的对齐的问题。也许您需要建立一个表格以按照您想要的方式排列所有内容,也许它是其他东西,但也许结束这个问题并就该问题提出另一个重新聚焦的问题是有意义的。
  • 非常感谢您的帮助。通过更改在 tkinter 中呈现列表元素的方式,我找到了一种解决方法。你能告诉我如何结束这个问题吗?
【解决方案2】:

下面这样的东西怎么样,它使用了超出范围的切片不会引发错误的事实:

my_list = ['Beef','Chicken','Eggs','Lamb','Nuts','Pork','Potatoes']

for i in range(0, len(my_list), 2):
    print(' '.join(f"-- {s:10}" for s in my_list[i:i+2]))

输出:

-- Beef       -- Chicken
-- Eggs       -- Lamb
-- Nuts       -- Pork
-- Potatoes

或者如果要获取单个字符串,可以嵌套join

output = '\n'.join(' '.join(f"-- {s:10}" for s in my_list[i:i+2]) for i in range(0, len(my_list), 2))

【讨论】:

  • 与迄今为止提供的其他答案一样,如果列表中还有其他元素,我仍然会遇到问题。 my_list = ['Beef','Chicken','Eggs','Lamb','Nuts','Pork','Potatoes','Dairy'] as Dairy 不会与 Potatoes 对齐
【解决方案3】:

给你:-)

可变列,验证最长的单词是否合适,应该非常有效

# Figure out the number of columns you wish to have in your table.
COLUMNS = 2

my_list = ['Beef','Chicken','Eggs','Lamb','Nuts','Pork','Potatoes']

# Figure our the length of the longest word in the list
longest_word_length = max(map(len,my_list))

# Create a format string that will add some spacing to the list
format_string = f'-- {{0:{longest_word_length+2}}}'

output = []

# Format all the items in the list
for index, item in enumerate(my_list, start=1):
    output.append(format_string.format(item))
    if index % COLUMNS == 0:
        output.append('\n')

print(''.join(output))

您也可以将tabulate"plain" 格式一起使用,这是一种简单的方法。

【讨论】:

  • 我仍然遇到一些问题,例如my_list=['Beef','Chicken','Eggs','Lamb','Nuts','Pork','Potatoes','Dairy']my_list=['Beeeeeeeeeeeef','Chicken','Eggs','Lamb','Nuts','Pork','Potatoes','Dairy']。由于我无法控制输入(我从文件中读取,并且文件可以更改),有没有办法解决这个问题?
  • 我会按照你的建议尝试使用制表模块,谢谢:)
猜你喜欢
  • 1970-01-01
  • 2013-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多