我开发了一个函数,从给定的数字序列中提取日期并重新格式化它。
这是代码:
from datetime import datetime as dt
def format_dates(field):
n = len(field)
match = False
i = 0
while match is False:
try:
# Take the last four digits
year = int(field[-4 - i:n - i])
except ValueError:
return ''
# Check if this year is between today's year +/- (15, 100)
if (1919 <= year <= 2019):
# Check if there are other 4 digits before these 4 ones
if (len(field[-8 - i:n - i]) == 8):
try:
f_date = dt.strptime(field[-8 - i:n - i],
'%d%m%Y').strftime('%d/%m/%Y')
match = True
return f_date
except ValueError:
pass
else:
return ''
i += 1
解释:
这一职能:
输入:‘1303201949’
这个函数工作得很好,但是它处理错误的方式看起来很难看。另外,我认为它不是优化的(同样的例外是重复的,很多返回和代码似乎不优雅)。
如何重新格式化代码并使其更加优化?
发布于 2019-10-08 10:36:14
如果算法找不到日期,则引发异常比返回''
更容易。如果此函数的用户不测试该哨兵值,则返回前哨值而不是异常会导致意外行为。
评论应该解释你为什么做某事,而不是怎么做。# Take the last four digits
只告诉您代码本身。我宁愿在field[-4 - i:n - i]
上评论为什么您做n - i
而不是只做-i
。
与其嵌套许多if-子句,不如测试条件和continue
的负值,这样代码的其余部分就更少嵌套了。
不要测试condition is True
。只要做condition
。在Python中,许多值可以在测试中充当True
或False
。
无论如何,您的match
从未被使用过;当您将其设置为True
时,您还将返回结果,因此while True:
在这里就足够了。
field
这是一个非常不清楚的变量名。此方法不包含字符串格式的日期,那么为什么不这样调用参数呢?
你的代码现在做了两件事。它在字符串中查找日期,并将该日期转换为其他格式。最好将这两件事分开,然后返回一个datetime.datetime
,让这个方法的调用者担心如何正确格式化。
while True
您使用的是带有递增计数器的while True
-loop。更好的方法是使用for i in range(...)
或使用itertools.count
:for i in itertools.count()
。在这种情况下,您知道只会有len(field) - 7
迭代,所以您最好使用它。
您将显式测试子字符串是否有8个字符长,然后测试其格式是否正确。通过将while True
更改为for
-loop,您知道子字符串将有8个字符长。然后,首先尝试将其转换为datetime
,然后检查年份是否正确,这是有意义的:
def format_dates2(date_string):
n = len(date_string)
for i in range(n - 7):
sub_string = date_string[-(8 + i) : n - i]
# not just -i because that fails at i==0
try:
date = dt.strptime(sub_string, "%d%m%Y")
except ValueError:
continue
if not (1919 <= date.year <= 2019):
continue
return date
raise ValueError("Date not in the correct format")
https://codereview.stackexchange.com/questions/230365
复制相似问题