Что является хорошей альтернативой для переключения для ввода строки Python? - PullRequest
0 голосов
/ 19 мая 2019

Я сканирую серию веб-страниц и систематизирую их содержимое в базе знаний в памяти. Мне нужно выполнить другой код в зависимости от моего ввода строки, который сканируется из заголовков веб-сайта.

tags = browser.find_elements_by_xpath("//div[@class='main-content-entry']/h2")
for tag in tags:
  heading = tag.get_attribute("textContent").lower().strip()
  content = tag.parent
  if heading.find("overview") != -1:
    # do this
  elif heading.find("takeaways") != -1:
    # do that
  # do more elifs
  else:
    # do something else

Прямо сейчас я реализовал это как выражение if-elif-else. Я видел ответы по всему сайту, предлагающие использовать dicts, но насколько я могу судить, это зависит от того, является ли ввод точным соответствием ключу. Однако в моем случае точное совпадение не всегда возможно из-за несоответствий со стороны владельца сайта.

Страницы достаточно структурированы, чтобы я знал, как называются названия заголовков, поэтому я могу заранее определить «ключи» в своем коде. Тем не менее, есть некоторые опечатки и небольшие варианты на некоторых из более чем 100 страниц для некоторых заголовков. Например:

  • Сборы и финансирование
  • Тарифы
  • Сборы и финансирование
  • Сертификаты
  • Сертификат
  • Сертификат и экзамены
  • экзамены и сертификаты

Лучшее, что я могу сделать, как и сейчас, - это сначала просмотреть страницы, идентифицировать весь набор заголовков, а затем вручную определить подстроки для использования в моем коде, чтобы избежать повторения.

Учитывая вышесказанное, есть ли лучший способ, чем итеративное выполнение цепочечного оператора if-elif-else?

Редактировать

Предлагаемые ответы в Замены для оператора switch в Python? не работают в моей ситуации. Возьмите для примера:

def do_this(heading):
  return {
    "overview": do_overview(),
    "fees": do_fees(),
    # ...
  }[heading]

Это было бы предложенное выполнение ответами на этот вопрос. Но как мне вернуть do_fees(), если heading равно "fees & funding", "fees", "fees &funding" и т. Д. И т. Д.? Мне нужно выполнить правильную функцию, если значение ключа является подстрокой heading.

Ответы [ 2 ]

2 голосов
/ 19 мая 2019

Учитывая вышесказанное, есть ли лучший способ, чем итеративное выполнение цепочечного оператора if-elif-else?

Нет необходимости непосредственно искать значения в словареиспользуя определенные ключи.Вы можете просто использовать словарь для сжатия логики разбора:

def extract_overview(content):
    ...

def extract_takeaways(content):
    ...

EXTRACTORS = {
    'overview': extract_overview,
    'takeaways': extract_takeaways,
    ...
}

for tag in tags:
    heading = tag.get_attribute("textContent").lower().strip()
    content = tag.parent

    for substring, function in EXTRACTORS.items():
        if substring in heading:
            result = function(content)
            break
    else:
        # No extractor was found
0 голосов
/ 19 мая 2019

Если вы хотите сопоставить опечатанные строки, вам понадобится некое нечеткое сопоставление для некоторых ваших входных данных. Однако для тех, кто хорошо сформирован, вы можете получить преимущества линейного времени оператора switch, настроив подход словаря. (это имеет значение, только если у вас много дел).

funcs = {
    "certificates": lambda: "certificates",
    "fees": lambda: "fees",
}

headings =['Fees & Funding', 'Fees', 'Fees &Funding', 'Certificates',
           'Certificate', 'Certificat & Exams', 'Exams & Certificates']

def do_this(heading):
    words = heading.lower().split()
    funcs_to_call = [funcs[word] for word in words if word in funcs]
    if len(funcs_to_call) == 1:
        return funcs_to_call[0]()
    elif len(funcs_to_call) == 0:
        return 'needs fuzzy matching'
    else:
        #alternatively treat it as being in multiple categories.
        raise ValueError("This fits more than one category")


for heading in headings:
    print(heading, parse(heading), sep = ': ')
#outputs:
Fees & Funding: fees
Fees: fees
Fees &Funding: fees
Certificates: certificates
Certificate: needs fuzzy matching
Certificat & Exams: needs fuzzy matching
Exams & Certificates: certificates

Если вы можете предсказать типы опечаток, с которыми вы столкнетесь, вы можете заранее очистить строки, чтобы получить более точные совпадения, такие как удаление символов и создание множественного числа слов.

...