我很难理解为什么我的循环没有从dd / mm / yyyy格式的日期元组列表中删除无效日期。这是我到目前为止所拥有的:
dates = [('12','10','1987'),('13','09','2010'), ('34','02','2002'), ('02','15','2005'),('37','10','2016'),('39','11','2001')]
print(dates)
for date in dates :
day = int(date[0])
month = int(date[1])
year = int(date[2])
if day > 31 :
dates.remove(date)
if month > 12 :
dates.remove(date)
print(dates)
和结果:
[('12', '10', '1987'), ('13', '09', '2010'), ('34', '02', '2002'), ('02', '15', '2005'), ('37', '10', '2016'), ('39', '11', '2001')]
[('12', '10', '1987'), ('13', '09', '2010'), ('02', '15', '2005'), ('39', '11', '2001')]
我是一个初学者,任何帮助将不胜感激。
答案 0 :(得分:3)
请不要修改要遍历的列表的(长度)。而是使用例如临时列表:
dates = [('12','10','1987'),('13','09','2010'), ('34','02','2002'), ('02','15','2005'),('37','10','2016'),('39','11','2001')]
print(dates)
out = []
for date in dates :
day = int(date[0])
month = int(date[1])
year = int(date[2])
if day > 31 or month > 12:
continue
out.append(date)
dates = out
print(dates)
continue
语句跳回到循环的第一行,因此不需要的日期将被跳过。
评论程序的“日期检查”功能:可能很难根据自己的规则来确定哪些日期可以接受,哪些日期不能接受。例如,以2月29日为例,它仅每四年有效一次。
您可以做的是使用datetime
库尝试将字符串解析为datetime对象,如果解析失败,您就知道日期是非法的。
import datetime as dt
dates = [('12','10','1987'),('13','09','2010'), ('34','02','2002'), ('02','15','2005'),('37','10','2016'),('39','11','2001')]
def filter_bad_dates(dates):
out = []
for date in dates:
try:
dt.datetime.strptime('-'.join(date), '%d-%m-%Y')
except ValueError:
continue
out.append(date)
return out
dates = filter_bad_dates(dates)
print(dates)
此try - except
模式也称为“鸭子输入”:
如果它看起来像日期,并且像正确的日期一样被解析,则可能是正确的日期。
答案 1 :(得分:1)
您可以通过以下列表理解轻松实现这一目标:
dates = [('12','10','1987'),('13','09','2010'), ('34','02','2002'), ('02','15','2005'),('37','10','2016'),('39','11','2001')]
dates = [date for date in dates if int(date[1]) < 12 and int(date[0]) < 31]
print(dates)
输出:
[('12', '10', '1987'), ('13', '09', '2010')]
答案 2 :(得分:0)
我喜欢@AnnZen的理解方法(+1),尽管我倾向于在浪费一些时间和空间的情况下变得更具象征性:
dates = [ \
('12', '10', '1987'), \
('13', '09', '2010'), \
('34', '02', '2002'), \
('02', '15', '2005'), \
('37', '10', '2016'), \
('39', '11', '2001'), \
]
dates = [date for (day, month, _), date in zip(dates, dates) if day < '31' and month < '12']
print(dates)
输出
> python3 test.py
[('12', '10', '1987'), ('13', '09', '2010')]
>
就@ np8的“从不修改正在循环的列表”而言,这是一个极好的建议。但是,再次,我可能会浪费一些空间来提前进行复制,以使代码更简单:
for date in list(dates): # iterate over a copy
day, month, _ = date
if int(day) > 31 or int(month) > 12:
dates.remove(date)
尽管最后,@ np8通过datetime
的过滤似乎是最可靠的解决方案。 (+1)