Странно Python Поведение с условными операторами - PullRequest
0 голосов
/ 06 мая 2020

Здравствуйте, у меня есть следующий список:

lines = ['', '', ' ', '', ' ', '', 'FA19 CHEM 102 3', 'FA19 CHEM 104 4', 'FA19 CLCV 115 ADB', 'FA19 CS 101 6', 'FA19 CS 125 PRO', 'FA19 CS 126 SL1', 'FA19 CS 173 BL2', 'FA19 ECON 1-- 7', 'FA19 ENG 100 CSA', '', '3.0 PS', '3.0 PS', '3.0 A', '3.0 PS', '4.0 PS', '3.0 A-', '3.0 A-', '3.0 PS', '0.0 S', '', '', '', '5/6', '', '', '5/4/2020', '', '', '', 'FA19 MATH 220 1', 'FA19 MATH 220 5', 'FA19 MATH 231 2', 'FA19 MATH 241 BL1', 'FA19 RHET 105 1', 'SP20 CS 225 AL2', 'SP20 CS 233 AL2', 'SP20 CWL 207 AL1', 'SP20 KIN 249 ON', 'FA20 CLCV 224 ADB', 'FA20 EPSY 220 OL', 'FA20 MATH 415 AL3', '', '0.0 PS >D', '5.0 PS', '3.0 PS', '4.0 A', '4.0 PS', '4.0 IP', '4.0 IP', '3.0 IP', '3.0 IP', '3.0 IP', '3.0 IP', '3.0 IP', '', '', '', '', '', '', '', '', '', '\uf00c', '']

Я пытаюсь удалить все строки в списке, которые являются либо пустыми строками, либо пробелами, либо следуют форматам даты для дат '5/6' и «04.05.2020». Для этого у меня есть следующий код:

    for s in lines:
        trans = re.sub('^([1-9]|1[012])[/]([0-9]|[1-9][0-9])[/](19|20)\d\d$', '', s)
        trans = re.sub('^([1-9]|1[012])[/]([0-9]|[1-9][0-9])$', '', trans)
        if (trans == '' or trans == ' '):
            lines.remove(s)

Я могу заверить вас, что мое регулярное выражение работает правильно, однако этот код не удаляет строку «5/6» из списка. Но если изменить для l oop, чтобы пропустить строку в списке, которая является пустой строкой или пробелами как таковыми:

    for s in lines:
        if (s == '' or s == ' '):
            continue
        trans = re.sub('^([1-9]|1[012])[/]([0-9]|[1-9][0-9])[/](19|20)\d\d$', '', s)
        trans = re.sub('^([1-9]|1[012])[/]([0-9]|[1-9][0-9])$', '', trans)
        if (trans == '' or trans == ' '):
            lines.remove(s)

, тогда строка '5/6' удаляется из списка. Что происходит в мире? Я просто упускаю что-то до неприличия очевидное?

1 Ответ

4 голосов
/ 06 мая 2020

Вы изменяете итерируемый объект, проходя по нему цикл, что является большим запретом. (Dicts замечают это и завершаются ошибкой RuntimeError, списки - нет.)

Я бы предложил провести рефакторинг до функции предиката фильтра и понимания списка:

def is_valid(s):
    trans = re.sub('^([1-9]|1[012])[/]([0-9]|[1-9][0-9])[/](19|20)\d\d$', '', s)
    trans = re.sub('^([1-9]|1[012])[/]([0-9]|[1-9][0-9])$', '', trans)
    return not trans.strip()  # String without leading/trailing spaces is empty

lines = [line for line in lines if is_valid(line)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...