格式化字符串与串联

wjk*_*2a1 32 python string-formatting

我看到很多人使用这样的格式字符串:

root = "sample"
output = "output"
path = "{}/{}".format(root, output)
Run Code Online (Sandbox Code Playgroud)

而不是简单地连接像这样的字符串:

path = root + '/' + output
Run Code Online (Sandbox Code Playgroud)

格式化字符串是否具有更好的性能还是仅适用于外观?

kay*_*kay 27

这只是为了看起来.您可以一目了然地看到格式是什么.我们中的许多人比可读性更好于微优化.

让我们来看看IPython的内容%timeit:

Python 3.7.2 (default, Jan  3 2019, 02:55:40)
IPython 5.8.0
Intel(R) Core(TM) i5-4590T CPU @ 2.00GHz

In [1]: %timeit root = "sample"; output = "output"; path = "{}/{}".format(root, output)
The slowest run took 12.44 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 5: 223 ns per loop

In [2]: %timeit root = "sample"; output = "output"; path = root + '/' + output
The slowest run took 13.82 times longer than the fastest. This could mean that an intermediate result is being cached.
10000000 loops, best of 5: 101 ns per loop

In [3]: %timeit root = "sample"; output = "output"; path = "%s/%s" % (root, output)
The slowest run took 27.97 times longer than the fastest. This could mean that an intermediate result is being cached.
10000000 loops, best of 5: 155 ns per loop

In [4]: %timeit root = "sample"; output = "output"; path = f"{root}/{output}"
The slowest run took 19.52 times longer than the fastest. This could mean that an intermediate result is being cached.
10000000 loops, best of 5: 77.8 ns per loop
Run Code Online (Sandbox Code Playgroud)

  • @comte你需要一个前面的f,但是是的. (12认同)
  • 请注意,从Python 3.6开始,您可以使用path ="{root}/{output}",这非常简单...... (7认同)

Fur*_*rge 11

与大多数事情一样,会有性能差异,但问问自己"如果这更快,那真的很重要吗?".该root + '/' output方法快速简便地输入.但是,如果要打印多个变量,这很难快速阅读

foo = "X = " + myX + " | Y = " + someY + " Z = " + Z.toString()
Run Code Online (Sandbox Code Playgroud)

VS

foo = "X = {} | Y= {} | Z = {}".format(myX, someY, Z.toString())
Run Code Online (Sandbox Code Playgroud)

哪个更容易理解发生了什么?除非你真的需要表现出色,否则选择最容易阅读和理解的方式


Lig*_*ica 11

它不仅适用于"外观",也适用于强大的词汇类型转换; 它也是国际化的必要条件.

您可以根据选择的语言换出格式字符串.

在源代码中加入了一长串字符串连接,这实际上无法正常执行.


Eri*_*mar 11

我同意格式化主要用于可读性,但自从3.6中的f字符串发布以来,表格在性能方面已经转变.我也认为f字符串更易读/可维护,因为1)它们可以像大多数常规文本一样被左右读取; 2)由于变量是字符串内的,因此避免了连接的间隔相关缺点.

运行此代码:

from timeit import timeit

runs = 1000000


def print_results(time, start_string):
    print(f'{start_string}\n'
          f'Total: {time:.4f}s\n'
          f'Avg: {(time/runs)*1000000000:.4f}ns\n')


t1 = timeit('"%s, %s" % (greeting, loc)',
            setup='greeting="hello";loc="world"',
            number=runs)
t2 = timeit('f"{greeting}, {loc}"',
            setup='greeting="hello";loc="world"',
            number=runs)
t3 = timeit('greeting + ", " + loc',
            setup='greeting="hello";loc="world"',
            number=runs)
t4 = timeit('"{}, {}".format(greeting, loc)',
            setup='greeting="hello";loc="world"',
            number=runs)

print_results(t1, '% replacement')
print_results(t2, 'f strings')
print_results(t3, 'concatenation')
print_results(t4, '.format method')
Run Code Online (Sandbox Code Playgroud)

在我的机器上产生这个结果:

% replacement
Total: 0.3044s
Avg: 304.3638ns

f strings
Total: 0.0991s
Avg: 99.0777ns

concatenation
Total: 0.1252s
Avg: 125.2442ns

.format method
Total: 0.3483s
Avg: 348.2690ns
Run Code Online (Sandbox Code Playgroud)

这个答案给出了对不同问题的类似答案.

  • 我认为 f string 具有全部 3 个:可读性、简洁(或易于编写)和最优化。我很好奇其他开发人员的想法。 (2认同)

Hal*_*ius 9

绑定数据时,字符串格式没有数据类型.在连接中,我们必须相应地输入或转换数据.

例如:

a = 10
b = "foo"
c = str(a) + " " + b
print c
> 10 foo
Run Code Online (Sandbox Code Playgroud)

它可以通过字符串格式化来完成:

a = 10
b = "foo"
c = "{} {}".format(a, b)
print c
> 10 foo
Run Code Online (Sandbox Code Playgroud)

这样的with-in占位符{} {},我们假设有两件事情要进一步发展,即在这种情况下,是ab.


Cyz*_*far 7

从Python 3.6开始,您可以在字符串之前添加文字字符串内插f

root = "sample"
output = "output"
path = f"{root}/{output}"
Run Code Online (Sandbox Code Playgroud)