您可以使用生成器查找所有位置,并使用min() 查找最左侧的位置:
positions = (s.find(sub), sub) for sub in (s1, s2, s3))
leftmost = min((pos, sub) for pos, sub in positions if pos > -1)[1]
这对每个子字符串只运行一次s.find(),过滤掉任何不存在的子字符串。如果根本没有匹配的子字符串,min() 将抛出 ValueError 异常;你可能想抓住它。
这确实会扫描字符串 3 次;如果测试的子字符串的数量足够大,您可能希望构建一个 trie structure,将索引循环到 s 并测试该位置的字符是否存在于 trie 中:
def make_trie(*words):
root = {}
for word in words:
current = root
for letter in word:
current = current.setdefault(letter, {})
# insert sentinel at the end
current[None] = None
return root
def find_first(s, trie):
for i in range(len(s)):
pos, current, found = i, trie, []
while pos < len(s) and s[pos] in current:
found.append(s[pos])
current = current[s[pos]]
if None in current: # whole substring detected
return ''.join(found)
pos += 1
leftmost = find_first(s, make_trie(s1, s2, s3))
trie 可以重复用于多个字符串。