【问题标题】:Is there a faster way to get input in python?有没有更快的方法在 python 中获取输入?
【发布时间】:2012-10-08 14:53:21
【问题描述】:

在编码比赛中,我们会遇到如下输入:

2 3

4 5

所以我们执行以下操作:

m, n = [int(x) for x in raw_input().split(' ')]

有没有更快的方法来做同样的事情?

【问题讨论】:

  • “更快”是什么意思?执行时间还是更少的代码?

标签: python performance input


【解决方案1】:

出于所有实际目的,这大约是您能获得的最快速度。在某些机器上,如果您使用 map 而不是列表解析,您可能会看到订单加速或几个百分点,但这不能保证。

这是我机器上的一些快速计时:

from itertools import imap
#map
>>> timeit.timeit('x,y = map(int,line.split(" "))','from __main__ import line')
4.7857139110565186
>>> timeit.timeit('x,y = map(int,line.split())','from __main__ import line')
4.5680718421936035
#list comprehension
>>> timeit.timeit('x,y = [int(x) for x in line.split(" ")]','from __main__ import line')
4.3816750049591064
>>> timeit.timeit('x,y = [int(x) for x in line.split()]','from __main__ import line')
4.3246541023254395
#itertools.imap
>>> timeit.timeit('x,y = imap(int,line.split(" "))','from __main__ import line,imap')
4.431504011154175
>>> timeit.timeit('x,y = imap(int,line.split())','from __main__ import line,imap')
4.3257410526275635
#generator expression
>>> timeit.timeit('x,y = (int(x) for x in line.split(" "))','from __main__ import line')
4.897794961929321
>>> timeit.timeit('x,y = (int(x) for x in line.split())','from __main__ import line')
4.732620000839233

令人惊讶的是,split() 似乎比 split(" ") 表现更好。


如果您保证使用 0 到 9 之间的数字的 ascii 输入,则可以使用 ord 做得更好:

>>>timeit.timeit('x,y = [ord(x)-48 for x in line.split(" ")]','from __main__ import line')
1.377655029296875
>>> timeit.timeit('x,y = [ord(x)-48 for x in line.split()]','from __main__ import line')
1.3243558406829834

但这对您的输入施加了严格的限制。


您可以尝试另一个想法(我不知道性能影响会是什么),但您可以从sys.stdin 阅读您的行:

import sys
for line in sys.stdin:
    x,y = [ord(x)-48 for x in line.split()]

【讨论】:

  • split()split(" ") 实际上并没有做同样的事情...docs.python.org/library/stdtypes.html#str.split
  • @JonClements -- 我知道他们不一样。 split()split(None) 是一样的。然而,split()split(" ")更通用,这就是为什么我很惊讶它更快(它需要对"\t" 进行测试,而不仅仅是' ',或者运行' ' 而不是单个 ' ' 例如)
  • 我猜 split() 可能在 C 中使用类似 strtok(str, " \t") 的东西来处理连续的分隔符......而 split(' ') 必须反对这种行为(也可能使用''s) 构建更大的结果列表
【解决方案2】:

使用map(),与内置函数一起使用时比列表推导更快:

m, n = map(int, raw_input().split())

【讨论】:

  • 是的,我知道这一点。我自己做了很多次计时(并得到了相互矛盾的结果)。我要说的是,结果可能因机器而异,而且这种微优化不太可能产生任何真正的影响。
  • 关于在我的提交中使用地图,执行时间从 3.86 秒减少到 3.64 秒
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-08
  • 1970-01-01
  • 2013-02-12
  • 1970-01-01
相关资源
最近更新 更多