可变数量的格式参数

时间:2013-06-27 16:03:47

标签: python python-3.x

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

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循环中创建一个字符串然后解析并评估它吗?我不知道这样做的语法。或者,如果有更多的pythonic方式,我也很想知道。

提前致谢。

4 个答案:

答案 0 :(得分:1)

我的印象是,您还希望能够将新项目随机添加到每个键的列表中。我很无聊,所以我说为什么不,并写下以下代码。它将找到每个键值的每个条目的最长长度并将其放在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! 

如果你想要一条线,那我恐怕无法帮助你:( 也许还有一种更简洁的方法可以进行第二次循环,但这就是我能想到的几个小时的睡眠时间。

答案 1 :(得分:0)

你的意思是你想做类似的事情:

list_var = [k] + v[:2]

如果值列表中的项目太多(这只是删除多余的项目),这将有效。

答案 2 :(得分:0)

如果我理解你的问题,这是你想要的格式字符串:

"{:<{}} " * 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()):

答案 3 :(得分:0)

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

为了说明这一点,我已经将您的代码字典中显示的几个条目中的值添加到下面的值中。简单地忽略前两个之外的值条目,但您可以通过根据需要扩展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