我使用以下代码从字符串中提取日期:
try:
my_date = datetime.strptime(input_date, "%Y-%m-%d").date()
except ValueError:
my_date = None
如果我运行750,000次,则需要19.144秒(使用cProfile确定).现在我用以下(丑陋的)代码替换它:
a= 1000 * int(input_date[0])
b= 100 * int(input_date[1])
c= 10 * int(input_date[2])
d= 1 * int(input_date[3])
year = a+b+c+d
c= 10 * int(input_date[5])
d= 1 * int(input_date[6])
month = c+d
c= 10 * int(input_date[8])
d= 1 * int(input_date[9])
day = c+d
try:
my_date = date(year, month, day)
except ValueError:
my_date = None
如果我运行750,000次,则只需5.946秒.但是,我发现代码真的很难看.有没有另一种快速的方法从字符串中提取日期,而不使用strptime?
解决方法:
是的,如果您放弃了很多灵活性和验证,那么解析日期的方法比datetime.strptime()更快. strptime()允许带有和不带零填充的数字,它只匹配使用正确分隔符的字符串,而“丑陋”版本则不匹配.
你应该总是使用timeit
module进行时间试验,它比cProfile更准确.
实际上,你的“丑陋”方法是strptime()的两倍:
>>> from datetime import date, datetime
>>> import timeit
>>> def ugly(input_date):
... a= 1000 * int(input_date[0])
... b= 100 * int(input_date[1])
... c= 10 * int(input_date[2])
... d= 1 * int(input_date[3])
... year = a+b+c+d
... c= 10 * int(input_date[5])
... d= 1 * int(input_date[6])
... month = c+d
... c= 10 * int(input_date[8])
... d= 1 * int(input_date[9])
... day = c+d
... try:
... my_date = date(year, month, day)
... except ValueError:
... my_date = None
...
>>> def strptime(input_date):
... try:
... my_date = datetime.strptime(input_date, "%Y-%m-%d").date()
... except ValueError:
... my_date = None
...
>>> timeit.timeit('f("2014-07-08")', 'from __main__ import ugly as f')
4.21576189994812
>>> timeit.timeit('f("2014-07-08")', 'from __main__ import strptime as f')
9.873773097991943
但是你的方法可以改进;你可以使用切片:
>>> def slicing(input_date):
... try:
... year = int(input_date[:4])
... month = int(input_date[5:7])
... day = int(input_date[8:])
... my_date = date(year, month, day)
... except ValueError:
... my_date = None
...
>>> timeit.timeit('f("2014-07-08")', 'from __main__ import slicing as f')
1.7224829196929932
现在几乎快了6倍.我还将int()调用移动到try中 – 除了在将字符串转换为整数时处理无效输入.
您也可以使用str.split()来获取部件,但这会使它再次稍微变慢:
>>> def split(input_date):
... try:
... my_date = date(*map(int, input_date.split('-')))
... except ValueError:
... my_date = None
...
>>> timeit.timeit('f("2014-07-08")', 'from __main__ import split as f')
2.294667959213257