繁体   English   中英

可变数量的格式参数

[英]Variable number of format arguments

我正在尝试根据列表中的项目数创建格式字符串变量

d = {1: ['Spices', 39], 2: ['Cannons', 43], 3: ['Tea', 31], 4: ['Contraband', 46], 5: ['Fruit', 38], 6: ['Textiles', 44]} 
d_max = [2, 11, 3]

for k,v in d.items():
    list_var = [k, v[0], v[1]]
    print(("{:<{}} " * 3).format(list_var[0], d_max[0], list_var[1], d_max[1], list_var[2], d_max[2]))

如果这些键具有或多或少的值而没有对响应进行硬编码,我想这样做。 我可以在for循环中创建一个字符串,然后解析并评估它吗? 我不知道这样做的语法。 或者,如果还有更Python的方式,我也想知道。

提前致谢。

我给您的印象是,您还希望能够将每个键的新项目随机添加到列表中。 我很无聊,所以我说为什么不这样做,并编写了以下代码。 它会找到每个键值的每个条目的最长长度,并将其放入d_max中,无论它是什么类型,只要可以将其转换为字符串,并且还支持将值随机添加(请参见d)的最后两行。 我试图对此做出很好的评论,但是如果需要的话请问一些问题。

d = {1: ['Spices', 39],
     2: ['Cannons', 43],
     3: ['Tea', 31],
     4: ['Contraband', 46],
     5: ['Fruit', 38],
     6: ['Textiles', 44],
     7: ['Odds and Ends', 100, 9999],
     8: ['Candies', 9999, 'It\'s CANDY!']} 
d_max = []

# Iterate over keys of d
for k in d:
    # Length of the key
    if len(d_max) <= 0:
        d_max.append(len(str(k)) + 1)
    elif len(str(k))+ 1 > d_max[0]:
        d_max[0] = len(str(k)) + 1 

    # Iterate over the length of the value
    for i in range(len(d[k])):
        # If the index isn't in d_max then this must be the longest
        # Add one to index because index 0 is the key's length
        if len(d_max) <= i+1:
            d_max.append(len(str(d[k][i])))
            continue
        # This is longer than the current one
        elif len(str(d[k][i])) + 1 > d_max[i+1]:
            d_max[i+1] = len(str(d[k][i])) + 1

for k,v in d.items():
    list_var = [k] + v

    # A list of values to unpack into the string
    vals = []
    # Add the value then the length of the space
    for i in range(len(list_var)):
        vals.append(list_var[i])
        vals.append(d_max[i])

    print(("{:<{}} " * len(list_var)).format(*vals))

输出:

1  Spices         39    
2  Cannons        43    
3  Tea            31    
4  Contraband     46    
5  Fruit          38    
6  Textiles       44    
7  Odds and Ends  100   9999         
8  Candies        9999  It's CANDY! 

如果您希望将所有内容都放在一行中,那么恐怕我无能为力:(也许还有一种更干净的方法可以执行第二个循环,但这就是我可以在几个小时的睡眠中想到的。

您是说要执行以下操作吗?

list_var = [k] + v[:2]

如果值列表中的项目过多,这将起作用(它将删除多余的项目)。

如果我正确理解了您的问题,这是您想要的格式字符串:

"{:<{}} " * len(list_var)

当然,在您的特定情况下,这要求您的列表( d_maxlist_var )都是正确的长度。 但它可以工作任何长度。

为了使实际用例更简洁,我可能将参数列表放在单独的语句中。 循环的一般情况如下所示:

args = []
for i in range(len(list_var)): # Build list of value/width arguments
    args += [list_var[i], d_max[i]]
print(("{:<{}} " * len(list_var)).format(*args))

或者,如果您是单线粘纸工,则可以使用这种怪异功能(与上面的显式循环相同,但更难阅读。):

# Ew
print(("{:<{}} " * len(list_var)).format(*functools.reduce(
                                            lambda a, i: a + [list_var[i], d_max[i]],
                                            range(len(list_var)),
                                            [])))

最后,正如其他人指出的那样,您不应该依赖词典来保留顺序。 如果必须通过字典键按顺序显示项目,那么在迭代之前,请务必对它们进行排序:

for k,v in sorted(d.items()):

如果我正确理解了您的问题,则以下内容将处理与字典中每个键相关联的越来越多的值。 实际上,每个条目在列表中不必具有相同数量的值。

为了说明这一点,我已经从字典中显示的几个条目中添加和删除了值,并将您的代码添加到下面的代码中。 只是忽略了前两个值之外的值条目,但是您可以通过根据需要扩展d_max字段宽度列表来轻松容纳更多值条目。

d = {1: ['Spices', 39, 'a'],
     2: ['Cannons', 43, 'b', 'c'],
     3: [],
     4: ['Contraband', 46, 'd'],
     5: ['Fruit'],
     6: ['Textiles', 44, 'f']}

d_max = [2, 11, 3]

for k,v in d.items():
    list_var = [k] + v[:2]
    pairs = (item for pair in zip(list_var, d_max) for item in pair)
    print(("{:<{}} " * len(list_var)).format(*pairs))

输出:

1  Spices      39
2  Cannons     43
3
4  Contraband  46
5  Fruit
6  Textiles    44

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM