Python 打印格式?哪一个更好

Python 打印格式?哪一个更好,python,Python,我一直很好奇 为什么python有不同的打印方式 比如说 print "this is ",a," and " ,b vs 有什么性能问题吗?那东西呢?这两者本质上是一样的。Python提供了格式化选项,以避免在复杂字符串中使用重复的逗号,这对键入和读取都会变得单调乏味。有时一种方法更适合特定情况,有时另一种方法更适合。第二种方法允许更好地格式化打印的参数。例如,您可以指定将数字格式化为十六进制,或指定要显示的浮点数的小数位数。在Python中也有很多“打印内容”的方法,包括更现代的方法,sy

我一直很好奇

为什么python有不同的打印方式

比如说

print "this is ",a," and " ,b
vs


有什么性能问题吗?那东西呢?

这两者本质上是一样的。Python提供了格式化选项,以避免在复杂字符串中使用重复的逗号,这对键入和读取都会变得单调乏味。有时一种方法更适合特定情况,有时另一种方法更适合。

第二种方法允许更好地格式化打印的参数。例如,您可以指定将数字格式化为十六进制,或指定要显示的浮点数的小数位数。

在Python中也有很多“打印内容”的方法,包括更现代的方法,
sys.stdout.write('foo')
,可能还有其他方法

关于
打印a、b、c
%
格式之间的区别,我通常使用前者主要用于调试输出,当您只需要在一组变量之间留空格时。当我想要精确的格式或对格式有更多的控制时,我使用
%
(实际上,现在我总是使用
str.format

例如:

print 'DEBUG:', var1, var2
与:

print 'Benchmarks took {0:.3f}s to run'.format(seconds)
另外,
%
str.format
格式更为通用——它们实际上不打印任何内容,而是返回字符串,您可以打印、写入文件、存储在数据库中、作为web响应发送等

关于性能——不要担心。这三种方法几乎都是快速的,过早的优化是万恶之源

我真的不想发布数字(因为这可能会鼓励错误的思维),但是
timeit
使用起来非常简单,我无法控制自己

C:\>python -m timeit -s "import cStringIO; s = cStringIO.StringIO()"
                     "print >>s, 'this is', 'a', 'test'"
100000 loops, best of 3: 3.39 usec per loop

c:\>python -m timeit -s "import cStringIO; s = cStringIO.StringIO()"
                     "print >>s, 'this is %s test' % 'a'"
1000000 loops, best of 3: 1.32 usec per loop

C:\>python -m timeit -s "import cStringIO; s = cStringIO.StringIO()"
                     "print >>s, 'this is {0} test'.format('a')"
1000000 loops, best of 3: 1.64 usec per loop

我不太清楚为什么打印a、b、c的
方法要慢得多,可能是一个实现细节。不过,别担心--打印到文件或屏幕上所需的时间可能远远超过字符串格式部分。

在性能问题上,这是laso类型的—不是时间问题,而是空间问题

这些陈述是相等的:

print "this is ",a," and " ,b
sys.stdout.write("this is ");sys.stdout.write(" ");sys.stdout.write(str(a));sys.stdout.write(" ");sys.stdout.write(" and ");sys.stdout.write(str(b));sys.stdout.write("\n");
print "this is %d and %d" %(a,b)
sys.stdout.write("this is %d and %d" %(a,b));sys.stdout.write("\n")
这些是平等的:

print "this is ",a," and " ,b
sys.stdout.write("this is ");sys.stdout.write(" ");sys.stdout.write(str(a));sys.stdout.write(" ");sys.stdout.write(" and ");sys.stdout.write(str(b));sys.stdout.write("\n");
print "this is %d and %d" %(a,b)
sys.stdout.write("this is %d and %d" %(a,b));sys.stdout.write("\n")
通常,如果打印多个元素,第一个版本被认为更快,因为一个接一个的ir写入流中

第二个版本需要处理和复制字符串的部分内容
“这是%d和%d”
。因此,如果您在其中有许多元素,并且多次格式化,并且字符串很大,那么它可能会比版本1占用更多内存


但是,由于Python是相当高的级别,我不能肯定什么性能更好。

在我们讨论打印内容的方法时,我只想对模块说一句话

import logging
# call once per process
logging.basicConfig(level=logging.INFO)

# do this when you would print
logging.info('this is %d and %d', a, b)

与打印一样简单,但很容易配置,当您突然意识到“哦,这个项目就要结束了”时,可以通过日期自动旋转、自定义格式等方式记录到文件中。

所以从性能角度来看,使用这两种格式都没有问题吗?不,确实没有。一般来说,打印在性能上不会太昂贵,而且其中任何一个都可以正常工作。我不知道两者之间有什么性能差异,但我不会担心性能,除非在内部循环中使用打印,这本身就是一个坏主意。@Fraz的可能性是,在命令提示窗口中呈现打印的字符串比格式化它的成本要高几个数量级。将其写入硬盘驱动器也是如此。您不包括第三个选项。请注意,“这种字符串格式化方法是Python3中的新标准,应该优先于新代码中字符串格式化操作中描述的%格式化方法。”哦,这里有一个关于这一点的问题:从本质上来说,这些打印内容的方法其实并没有什么不同。你提到的第二种方法只是一个字符串函数。例如,这也可以使用:
formatted=“这是%d和%d”%(a,b)
。选择后者(或
str.format()
)而不是字符串串联的原因是它更灵活、更强大。我似乎记得Python性能的一点是,避免解释器开销通常比微优化单个操作更重要。也就是说,您希望避免在Python中执行函数调用或循环列表的开销,而不是找出添加数字或打印字符串的最快方法。@millimoose,我不确定这是否正确。例如,
对于字符串中的s:output+=s
是一种非常慢的串接字符串的方法,而
output=''.join(strings)
是一种很快的方法——不用考虑字节码。在优化Python代码时,我几乎从未想过解释器。例外情况可能是调用Python函数的开销,正如您所提到的。例如,
lst.sort(key=operator.itemgetter('foo'))
lst.sort(key=lambda x:x['foo'))
快得多。这实际上就是我的意思。也就是说,xs:
中x的
往往比使用
join()
甚至
map()
或理解更慢,因为在解释器中更新局部变量的开销更大。(所有操作“一次完成”列表)@millimoose:是的,但这实际上是一个微观优化。在内部循环中使用
output+=s
的缺点是它是二次O(N^2),因为它必须在每个循环中构造/复制一个新字符串,而
str.join
是线性O(N)。算法复杂性的问题远远超过了解释器的关注。