LINUX.ORG.RU

Питон, разбор строки.

 , ,


0

1

Была поставлена задача:

The function should recognises if a subject line is stressful. A stressful subject line means that all letters are uppercase, and/or ends by at least 3 exclamation marks and/or contains at least one of the following “red” words «help», «asap», «urgent». Any of those «red» words can be spelled in different ways - «HELP», «help», «HeLp», «H!E!L!P!», «H-E-L-P», even in a very loooong way «HHHEEEEEEEEELLP»

is_stressful(«Hi») == False
is_stressful(«I neeed HELP») == True

Я решил таким образом:

def is_stressful(subj):
    stress_symbol   = "!!!"
    stress_words    = ["help", "asap", "urgent"]
    removed_symbols = ";-,.!"
    outdata         = " "

    if subj.isupper() or subj[-3:] == stress_symbol:
        return True

    subj = subj.lower()

    for x in range(len(subj)):
        if subj[x] == outdata[-1] or subj[x] in removed_symbols:
            continue
        else:
            outdata += subj[x]

    for x in outdata.split():
        if x in stress_words:
            return True

    return False
Вопрос: как разбираются правильно строки? Чтобы поменьше памяти и ресурсов? Особенно интересует убрать дубликаты и не испортить последовательность.



Последнее исправление: masterdilly (всего исправлений: 2)

Вот это вот какая-то жесть:

    for x in range(len(subj)):
        if subj[x] == outdata[-1] or subj[x] in removed_symbols:
            continue
        else:
            outdata += subj[x]

Во-первых, это не C, и for тут другой. Если ты перебираешь элементы чего-либо, то не надо перебирать их индексы из range (sic!):

    for x in subj:
        if x == outdata[-1] or x in removed_symbols:
            continue
        else:
            outdata += x

Во-вторых, можно просто немного сократить, хотя это не прироста (в отличие от лишних вызовов range, индексации и всего такого, но станет короче и проще (без continue):

    for x in subj:
        if x != outdata[-1] or x not in removed_symbols:
            outdata += x

Далее, вот так делать не надо:

subj[-3:] == stress_symbol

ведь есть замечательный метод, делающий прямо вот ровно-ровно то, что ты хочешь, и называющийся соответствующе:

subj.endswith(stress_symbol)

А то у тебя -3 волшебное число, где 3 = len(stress_symbol), да и вообще сбивает с толку и медленнее.

А вот это:

    for x in outdata.split():
        if x in stress_words:
            return True

    return False

Я бы записал так:

    return any(word in stress_words for word in outdata.split())

По-моему так читаемее. Хотя для новичка в Python (или в генераторах в нём, или кто не любит any) первый вариант может показаться читаемее. Тут не буду спорить, тем не менее, я бы написал так.

Psych218 ★★★★★
()
Последнее исправление: Psych218 (всего исправлений: 4)
Ответ на: комментарий от Psych218

Спасибо за Any и за Range. Так явно лучше. Просто в инете полно Сишников. Я не смог найти пример, где показано, как убирать дубликаты. Поверьте, этот еще не так страшен. Примеров бы на генераторы. Нигде не нашел. Вот это:

(word in stress_words for word in outdata.split())
Нигде не написано, как комбинировать IF и FOR с двумя последовательностями. Очень изящно.

masterdilly
() автор топика
Ответ на: комментарий от Psych218

Во-вторых, можно просто немного сократить

Некто морган с тобой не согласен:

Закон общей инверсии Закон де Моргана
¬(X /\ Y) = ¬X \/ ¬Y

anonymous
()
Ответ на: комментарий от anonymous

Упс. Спасибо за поправку. Конечно же там должно быть and вместо or.

Psych218 ★★★★★
()
Ответ на: комментарий от masterdilly

это вроде импорт целого модуля

В этом нет ничего плохого.

true_admin ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.