Как игнорировать недопустимые строки

#python #python-3.x

#python #python-3.x

Вопрос:

 import datetime

random_list = ["lol", "2020-10-05", "2020-09-11"]
date_list = []

for item in random_list:
    try:
        date = datetime.datetime.strptime(item, "%Y-%m-%d")
        date_list.append(date)
    except ValueError:
        print("Not a valid date foramt")


print(date_list)
  

В приведенном выше коде я в основном просматриваю некоторые random_list , и если я вижу строку с допустимым форматом даты, я хочу добавить ее в другой список, вызываемый date_list .

Я хочу добавлять только строки с допустимым форматом даты, что означает, что если я вижу случайную строку «foo», я хочу игнорировать ее и не добавлять к date_list .

Я думаю, что было бы лучшим и наиболее питоническим способом справиться с этим?

В идеале, если бы существовала какая-то логическая функция, которая сообщала бы мне, является ли строка, на которую я смотрю, датой, тогда я мог бы просто добавлять строки date_list , когда они возвращают True после проверки.

Мне бы хотелось подумать о том, как правильно я могу справиться с этим.

Комментарии:

1. Это больше похоже на codereview, чем на SO.

Ответ №1:

это довольно хороший способ сделать это, вы могли бы реализовать его с помощью понимания списка или с помощью filter функции

 random_list = ["lol", "2020-10-05", "2020-09-11"]

def validate(date_text):
    try: datetime.datetime.strptime(date_text, '%Y-%m-%d'); return True
    except ValueError: return False

random_list = list(filter(validate, random_list))

print(random_list)

#or 

[i for i in random_list if validate(i)]
  

оба дадут вам:

 ["2020-10-05", "2020-09-11"]
  

если вы хотите преобразовать его, проще всего использовать понимание списка с помощью filter

 [datetime.datetime.strptime(i, '%Y-%m-%d') for i in list(filter(validate, random_list))]
  
 [datetime.datetime(2020, 10, 5, 0, 0), datetime.datetime(2020, 9, 11, 0, 0)]
  

Комментарии:

1. == True тест не нужен

2. понимание списка с помощью filter может быть дешевле выражено без вызовов filter / list, выполнив inline if следующим образом: [datetime.datetime.strptime(i, '%Y-%m-%d') for i in random_list if validate(i)]

Ответ №2:

Ну, поскольку вы используете определенный формат ГГГГ-ММ-ДД, вы можете тривиально сделать это с помощью регулярных выражений. Что-то вроде этого:

 import re
import datetime
rDate = re.compile(r'^dddd-dd-dd$')

isDate = lambda d: rDate.match(d)
toDate = lambda d: datetime.datetime.strptime(d, "%Y-%m-%d")

random_list = ["lol", "2020-10-05", "2020-09-11"]
date_list = list(map(toDate, filter(isDate, random_list)))

print(date_list)
  

Я получаю этот результат:

 $ /bin/python ./dates.py
[datetime.datetime(2020, 10, 5, 0, 0), datetime.datetime(2020, 9, 11, 0, 0)]