[英]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_max
和list_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.