python - 打印输出时 , 和 + 的区别

标签 python string

快速但可能是愚蠢的问题。当我需要连接文本和数值以进行输出时,我通常会使用:

number = 4
print("Two plus two = " + str(number))

但有时我会看到:

number = 4
print("Two plus two =",number)

第二个示例不需要类型转换并添加前导空格,但除此之外它们做同样的事情。任何人都知道为什么有两种方法可以做同样的事情?哪种方法“更好”?

最佳答案

重要的是要理解 print("Two plus two = "+ str(number)) 中的连接操作与 print 无关并且发生在之前print 被调用。

让我们做一些计时:

from timeit import Timer

def with_concat():
    print("Two plus two = " + str(4))

def no_concat():
    print("Two plus two =", 4)

print(min(Timer(with_concat).repeat(100, 100)))
print(min(Timer(no_concat).repeat(100, 100)))

输出

0.0006760049999998685
0.0013034899999999627

与直觉相反(请参阅我对问题的评论,字符串连接可能很昂贵)连接示例实际上以可重现的方式更快(2 倍!)。但是为什么?

让我们检查字节码:

from dis import dis

def with_concat():
    print("Two plus two = " + str(4))

def no_concat():
    print("Two plus two =", 4)

dis(with_concat)

输出

 0 LOAD_GLOBAL              0 (print)
 2 LOAD_CONST               1 ('Two plus two = ')
 4 LOAD_GLOBAL              1 (str)
 6 LOAD_CONST               2 (4)
 8 CALL_FUNCTION            1
10 BINARY_ADD
12 CALL_FUNCTION            1
14 POP_TOP
16 LOAD_CONST               0 (None)
18 RETURN_VALUE

同时

dis(no_concat)

输出

 0 LOAD_GLOBAL              0 (print)
 2 LOAD_CONST               1 ('Two plus two =')
 4 LOAD_CONST               2 (4)
 6 CALL_FUNCTION            2
 8 POP_TOP
10 LOAD_CONST               0 (None)
12 RETURN_VALUE

从字节码来看,no_concat 应该更快(更短、更简单的代码)。

延迟必须来自 C 源代码(至少在 CPython 的情况下)。

让我们看看相关的行:

static PyObject *
builtin_print(PyObject *self, PyObject *args, PyObject *kwds)
{
    .
    .
    .

    for (i = 0; i < PyTuple_Size(args); i++) {
        if (i > 0) {
            if (sep == NULL)
                err = PyFile_WriteString(" ", file);
            else
                err = PyFile_WriteObject(sep, file,
                                         Py_PRINT_RAW);
            if (err)
                return NULL;
        }
        err = PyFile_WriteObject(PyTuple_GetItem(args, i), file,
                                 Py_PRINT_RAW);
        if (err)
            return NULL;
    }

    .
    .
    .
}

对我来说,使用 print(*args) 的开销似乎是由于重复调用 PyTuple_GetItem(args, i),而好处是在 print(a + lot + of + concatenated + strings) 上使用它只有当连接的字符串数量大到足以使连接成为瓶颈时(即比重复调用慢 PyTuple_GetItem(args, i)).

关于python - 打印输出时 , 和 + 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52354518/

相关文章:

python - 如何在 Python 中使用 Regex/Strip() 去除字符串末尾的随机字符?

python - 未封闭的 XML token

c - 在 C 中使用 strtok 将日期字符串转换为整数

java - 使用 split 方法拆分字符串

C++将字符串传递到管道中以传递给gnuplot

java - 在java中编码撇号

string - 与字符串的复杂模式匹配

python - 使用 python 删除 JSON 中的键时如何正确保持结构?

python - 将元组传递给接受 *args 和 **kwargs 的函数

python - 在同一列上按数字排序,然后按字母数字排序