使用Python字符串格式化与列表

143

我在Python 2.6.5中构造了一个字符串s,其中包含可变数量的%s令牌,与列表x中的条目数匹配。 我需要编写一个格式化的字符串。以下示例不起作用,但指示了我要做的事情。在此示例中,有三个%s令牌,而列表中有三个条目。

s = '%s BLAH %s FOO %s BAR'
x = ['1', '2', '3']
print s % (x)

我希望输出的字符串为:

1 BLAH 2 FOO 3 BAR


如果您正在寻找基于f-string的解决方案,可以参考Python 3.6中使用元组的格式化字符串字面值。 - FObersteiner
8个回答

190

你应该查看Python的format方法。然后,你可以定义你的格式化字符串如下:

>>> s = '{0} BLAH BLAH {1} BLAH {2} BLAH BLIH BLEH'
>>> x = ['1', '2', '3']
>>> print s.format(*x)
'1 BLAH BLAH 2 BLAH 3 BLAH BLIH BLEH'

2
OP的问题不在于方法,而在于参数的格式。%运算符只能解包元组。 - patrys
这会让s的构建变得更加复杂,因为我需要包含递增数字而不仅仅是每个位置的%ss以多种不同的步骤构建,所以只包含%s标记更容易。 - SabreWolfy
2
@SabreWolfy 如果您按照过程构造它,那么您可能会发现更容易为占位符命名,并使用字典来格式化生成的字符串:print u'%(blah)d BLAHS %(foo)d FOOS …' % {'blah': 15, 'foo': 4} - patrys
2
@SabreWolfy:在Python 2.7中,您可以省略字段编号:s = '{} BLAH {} BLAH BLAH {} BLAH BLAH BLAH' - Dennis Williamson
1
@kotchwane:函数是Python中的一个特殊关键字,它将作为列表的参数转换为参数列表 : )。在我们的情况下,x将把x的3个成员传递给format方法。 - Cédric Julien
显示剩余3条评论

129
print s % tuple(x)

用...代替

print s % (x)

6
(x)x是相同的。在Python中,将单个标记放在括号中没有任何意义。通常在foo = (bar,)中加括号可以使其更易于阅读,但是foo = bar,完全具有相同的功能。 - patrys
13
"print s % (x)" 是 OP 写的,我只是在引用他/她的话。 - infrared
我只是提供了一个语言提示,而不是批评你的答案(事实上我点赞了它)。你也没有写 foo = (bar, ) :) - patrys
3
我使用“(x)”符号来增加清晰度,同时如果你以后添加了其他变量,它也可以避免忘记括号。 - SabreWolfy
1
这是最好的答案!它比.format()更简单、更短,而后者不应该成为得票最高的答案!! - Apostolos
显示剩余2条评论

45

根据此资源页面,如果x的长度是可变的,我们可以使用:

', '.join(['%.2f']*len(x))

为列表x中的每个元素创建一个占位符。以下是示例:

x = [1/3.0, 1/6.0, 0.678]
s = ("elements in the list are ["+', '.join(['%.2f']*len(x))+"]") % tuple(x)
print s
>>> elements in the list are [0.33, 0.17, 0.68]

30
这里是一行代码。使用print()函数和format()方法迭代列表的简易回答。

以下是一个Python 3.x的示例:

sample_list = ['cat', 'dog', 'bunny', 'pig']
print("Your list of animals are: {}, {}, {} and {}".format(*sample_list))

在这里阅读有关使用format()的文档。


星号(*)的含义或功能是什么?您提供的文档链接似乎没有澄清这一点。 - kotchwane
4
@kotchwane,星号“展开”列表作为单个有序参数。f(*x)== f(x [0],x [1],...,x [n])。同样,两个星号(**)将字典扩展为关键字参数。 - Wacov

21

由于我刚学到这个很酷的东西(在格式化字符串内对列表进行索引),所以我正在为这个旧问题添加内容。

s = '{x[0]} BLAH {x[1]} FOO {x[2]} BAR'
x = ['1', '2', '3']
print (s.format (x=x))

输出:

1 BLAH 2 FOO 3 BAR

然而,我仍然没有弄清楚如何在格式化字符串的内部进行切片(例如:'"{x[2:4]}".format...),如果有人有想法,我很愿意弄清楚,但是我怀疑您可能无法这样做。


我有点好奇您在切片方面的使用场景。 - Michael
1
我没有真正的原因...我只是觉得能够这样做很有趣。 - Joran Beasley

12

这是一个有趣的问题!处理可变长度列表的另一种方法是构建一个函数,充分利用 .format 方法和列表拆包。在下面的示例中,我没有使用任何花哨的格式,但可以轻松更改以适应您的需求。

list_1 = [1,2,3,4,5,6]
list_2 = [1,2,3,4,5,6,7,8]

# Create a function that can apply formatting to lists of any length:
def ListToFormattedString(alist):
    # Create a format spec for each item in the input `alist`.
    # E.g., each item will be right-adjusted, field width=3.
    format_list = ['{:>3}' for item in alist] 

    # Now join the format specs into a single string:
    # E.g., '{:>3}, {:>3}, {:>3}' if the input list has 3 items.
    s = ','.join(format_list)

    # Now unpack the input list `alist` into the format string. Done!
    return s.format(*alist)

# Example output:
>>>ListToFormattedString(list_1)
'  1,  2,  3,  4,  5,  6'
>>>ListToFormattedString(list_2)
'  1,  2,  3,  4,  5,  6,  7,  8'

6

如果只是想将任意值填充到字符串列表中,可以使用以下方法,与@neobot的答案相同但更为现代且简洁。

>>> l = range(5)
>>> " & ".join(["{}"]*len(l)).format(*l)
'0 & 1 & 2 & 3 & 4'

如果你要连接的内容已经是某种结构化数据,我认为最好做的是像这样:
>>> data = {"blah": 1, "foo": 2, "bar": 3}
>>> " ".join([f"{k} {v}" for k, v in data.items()])
'blah 1 foo 2 bar 3'

1
x = ['1', '2', '3']
s = f"{x[0]} BLAH {x[1]} FOO {x[2]} BAR"
print(s)

输出结果为

1 BLAH 2 FOO 3 BAR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接