Python 字符串输入的 switch 有什么好的替代方法?
What's a good alternative to switch for Python string inputs?
我正在抓取一系列网页并将它们的内容组织到一个 in-memory 知识库中。我需要根据我的字符串输入执行不同的代码,这是从网站的标题中抓取的。
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 语句。我在网站上看到了建议使用字典的答案,但据我所知,这取决于输入是否与密钥完全匹配。然而,就我而言,由于网站所有者的不一致,并不总是能够完全匹配。
页面的结构足够我知道标题名称是什么,所以我可以在我的代码中提前定义 "keys"。但是,某些 hundred-over 页面中的某些标题存在拼写错误和轻微变体。例如:
- 费用和资金
- 费用
- 费用和资金
- 证书
- 证书
- 证书和考试
- 考试和证书
我目前所能做的最好的事情是首先扫描页面,识别整组标题,然后手动定义要在我的代码中使用的子字符串,以避免重复。
考虑到上述情况,是否有更好的方法来迭代执行链式 if-elif-else 语句?
编辑
Replacements for switch statement in Python? 中的建议答案不适用于我的情况。举个例子:
def do_this(heading):
return {
"overview": do_overview(),
"fees": do_fees(),
# ...
}[heading]
这将是该问题的答案所建议的实施方式。但是,当 heading
是 "fees & funding"
、"fees"
、"fees &funding"
等时,我如何 return do_fees()
等等?如果键值是 heading
.
的子字符串,我需要执行正确的函数
Considering the above, is there a better way then to iteratively execute a chained if-elif-else statement?
您无需使用特定键直接从字典中查找值。您可以只使用字典来压缩您的解析逻辑:
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
如果您想要匹配 typo-ed 个字符串,那么对于您的某些输入,您将需要某种模糊匹配。然而,对于那些结构良好的语句,您可以通过调整字典方法来获得 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
如果您能够预测您将要面对的拼写错误类型,您可以更早地清理字符串以获得更准确的匹配,例如删除符号和使单词复数。
我正在抓取一系列网页并将它们的内容组织到一个 in-memory 知识库中。我需要根据我的字符串输入执行不同的代码,这是从网站的标题中抓取的。
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 语句。我在网站上看到了建议使用字典的答案,但据我所知,这取决于输入是否与密钥完全匹配。然而,就我而言,由于网站所有者的不一致,并不总是能够完全匹配。
页面的结构足够我知道标题名称是什么,所以我可以在我的代码中提前定义 "keys"。但是,某些 hundred-over 页面中的某些标题存在拼写错误和轻微变体。例如:
- 费用和资金
- 费用
- 费用和资金
- 证书
- 证书
- 证书和考试
- 考试和证书
我目前所能做的最好的事情是首先扫描页面,识别整组标题,然后手动定义要在我的代码中使用的子字符串,以避免重复。
考虑到上述情况,是否有更好的方法来迭代执行链式 if-elif-else 语句?
编辑
Replacements for switch statement in Python? 中的建议答案不适用于我的情况。举个例子:
def do_this(heading):
return {
"overview": do_overview(),
"fees": do_fees(),
# ...
}[heading]
这将是该问题的答案所建议的实施方式。但是,当 heading
是 "fees & funding"
、"fees"
、"fees &funding"
等时,我如何 return do_fees()
等等?如果键值是 heading
.
Considering the above, is there a better way then to iteratively execute a chained if-elif-else statement?
您无需使用特定键直接从字典中查找值。您可以只使用字典来压缩您的解析逻辑:
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
如果您想要匹配 typo-ed 个字符串,那么对于您的某些输入,您将需要某种模糊匹配。然而,对于那些结构良好的语句,您可以通过调整字典方法来获得 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
如果您能够预测您将要面对的拼写错误类型,您可以更早地清理字符串以获得更准确的匹配,例如删除符号和使单词复数。