有多种字符串格式设置方法:

Python<2.6:“您好%s”%namePython 2.6+:“Hello{}”.format(name)(使用str.format)Python 3.6+:f“{name}”(使用f-string)

哪种情况更好?在什么情况下?


以下方法具有相同的结果,那么有什么区别?name=“爱丽丝”“你好%s”%name“您好{0}”.format(名称)f“您好{name}”#使用命名参数:“您好%(kwarg)s”%{'kwarg':name}“你好{kwarg}”.format(kwarg=name)f“您好{name}”字符串格式化何时运行,如何避免运行时性能损失?


如果您试图结束一个重复的问题,该问题只是在寻找一种格式化字符串的方法,请使用How do I put a variable value in a string?。


当前回答

在格式化正则表达式时,%可能会有所帮助。例如

'{type_names} [a-z]{2}'.format(type_names='triangle|square')

引发IndexError。在这种情况下,您可以使用:

'%(type_names)s [a-z]{2}' % {'type_names': 'triangle|square'}

这避免了将正则表达式写成“{type_names}[a-z]{{2}}”。当您有两个正则表达式时,这可能很有用,其中一个正则表达式单独使用而不使用格式,但两者的连接是格式化的。

其他回答

%比我测试的格式性能更好。

测试代码:

Python 2.7.2:

import timeit
print 'format:', timeit.timeit("'{}{}{}'.format(1, 1.23, 'hello')")
print '%:', timeit.timeit("'%s%s%s' % (1, 1.23, 'hello')")

结果:

> format: 0.470329046249
> %: 0.357107877731

Python 3.5.2

import timeit
print('format:', timeit.timeit("'{}{}{}'.format(1, 1.23, 'hello')"))
print('%:', timeit.timeit("'%s%s%s' % (1, 1.23, 'hello')"))

后果

> format: 0.5864730989560485
> %: 0.013593495357781649

在Python2中,差异很小,而在Python3中,%比格式快得多。

感谢@Chris Cogdon提供的示例代码。

编辑1:

2019年7月在Python 3.7.2中再次测试。

结果:

> format: 0.86600608
> %: 0.630180146

没有太大区别。我想Python正在逐步改进。

编辑2:

在有人在评论中提到python 3的f-string之后,我在python 3.7.2下测试了以下代码:

import timeit
print('format:', timeit.timeit("'{}{}{}'.format(1, 1.23, 'hello')"))
print('%:', timeit.timeit("'%s%s%s' % (1, 1.23, 'hello')"))
print('f-string:', timeit.timeit("f'{1}{1.23}{\"hello\"}'"))

结果:

format: 0.8331376779999999
%: 0.6314778750000001
f-string: 0.766649943

似乎f-string仍然比%慢,但比格式好。

但有一点是,如果您有嵌套的大括号,则不适用于格式,但%可以使用。

例子:

>>> '{{0}, {1}}'.format(1,2)
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    '{{0}, {1}}'.format(1,2)
ValueError: Single '}' encountered in format string
>>> '{%s, %s}'%(1,2)
'{1, 2}'
>>> 

如果您的python>=3.6,则F-字符串格式的文字是您的新朋友。

它更简单、更干净、性能更好。

In [1]: params=['Hello', 'adam', 42]

In [2]: %timeit "%s %s, the answer to everything is %d."%(params[0],params[1],params[2])
448 ns ± 1.48 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [3]: %timeit "{} {}, the answer to everything is {}.".format(*params)
449 ns ± 1.42 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [4]: %timeit f"{params[0]} {params[1]}, the answer to everything is {params[2]}."
12.7 ns ± 0.0129 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

PEP3101建议在Python3中用新的高级字符串格式替换%运算符,这将是默认值。

Python 3.6.7比较:

#!/usr/bin/env python
import timeit

def time_it(fn):
    """
    Measure time of execution of a function
    """
    def wrapper(*args, **kwargs):
        t0 = timeit.default_timer()
        fn(*args, **kwargs)
        t1 = timeit.default_timer()
        print("{0:.10f} seconds".format(t1 - t0))
    return wrapper


@time_it
def new_new_format(s):
    print("new_new_format:", f"{s[0]} {s[1]} {s[2]} {s[3]} {s[4]}")


@time_it
def new_format(s):
    print("new_format:", "{0} {1} {2} {3} {4}".format(*s))


@time_it
def old_format(s):
    print("old_format:", "%s %s %s %s %s" % s)


def main():
    samples = (("uno", "dos", "tres", "cuatro", "cinco"), (1,2,3,4,5), (1.1, 2.1, 3.1, 4.1, 5.1), ("uno", 2, 3.14, "cuatro", 5.5),) 
    for s in samples:
        new_new_format(s)
        new_format(s)
        old_format(s)
        print("-----")


if __name__ == '__main__':
    main()

输出:

new_new_format: uno dos tres cuatro cinco
0.0000170280 seconds
new_format: uno dos tres cuatro cinco
0.0000046750 seconds
old_format: uno dos tres cuatro cinco
0.0000034820 seconds
-----
new_new_format: 1 2 3 4 5
0.0000043980 seconds
new_format: 1 2 3 4 5
0.0000062590 seconds
old_format: 1 2 3 4 5
0.0000041730 seconds
-----
new_new_format: 1.1 2.1 3.1 4.1 5.1
0.0000092650 seconds
new_format: 1.1 2.1 3.1 4.1 5.1
0.0000055340 seconds
old_format: 1.1 2.1 3.1 4.1 5.1
0.0000052130 seconds
-----
new_new_format: uno 2 3.14 cuatro 5.5
0.0000053380 seconds
new_format: uno 2 3.14 cuatro 5.5
0.0000047570 seconds
old_format: uno 2 3.14 cuatro 5.5
0.0000045320 seconds
-----