我正在寻找最好的 most 效率最高的方法,以将单个字符串的末尾与预定义的字符串列表中的值进行匹配。
my_str='QWERTY'
my_lst=['QWE','QQQQ','TYE','YTR','TY']
match='TY'
或match=['TY']
在限制下
len(my_lst)
是已知的,但任意性可能会很长,可能约为30
my_lst
中的元素可能具有不同的len
,所以我不能每次都只检查my_str
的定义的最后一部分
对于my_str
以及my_lst
中的匹配元素,它们可以是字符串或列表,以效率更高的一种为准(请参见背景)
len(my_str)
大部分很小,不能超过8个字符
in
函数不会起作用,因为我需要完全在末尾进行匹配。
endswith
本身是没有用的,因为它只会return
一个Boolean
匹配项应该始终是唯一的或[]
,因为my_lst
中的任何元素都不会共享结尾
背景较弱可能会跳过
我从一个诸如['Q','W','E','R','T','Y']
之类的列表问题开始,这个问题将包含一个由1个字符串组成的列表的列表以进行匹配,并且我正在考虑将反向迭代作为[::-1]
来进行检查每个候选人。
然后我意识到可以串联内部列表,因为它们仅包含字符串,并且对结果字符串运行相同的逻辑。
最终,我遇到了this question的endswith
字符串方法,但这并不是我所需要的。此外,我的问题不能一概而论用os
模块或类似的模块来解决,因为它是字符串问题,而不是路径问题。
背景结束
我以两种方式做出自己的方法
match=filter(lambda x: my_str.endswith(x), my_lst)
match=[x for x in my_lst if my_str.endswith(x)]
我成功了,但是我想知道是否有某种内置的或最佳的方法来查找和返回匹配的结束值。
谢谢。
答案 0 :(得分:1)
这是使用trie或前缀树(在这种情况下,从技术上讲是后缀树)的一种方法。如果我们有三个潜在的后缀CA
,CB
和BA
,则我们的后缀树看起来像
e
/ \
A B
/ \ |
B C C
({e
是空字符串)我们从输入字符串的末尾开始并使用字符。如果我们遇到字符串的开头或不是当前节点的子元素的字符,则我们拒绝该字符串。如果到达树的叶子,那么我们接受字符串。这使我们可以更好地扩展到很多潜在的后缀。
def build_trie(suffixes):
head = {}
for suffix in suffixes:
curr = head
for c in reversed(suffix):
if c not in curr:
curr[c] = {}
curr = curr[c]
return head
def is_suffix(trie, s):
if not trie:
return True
for c in reversed(s):
try:
trie = trie[c]
except KeyError:
return False
if not trie:
return True
return False
trie = build_trie(['QWE','QQQQ','TYE','YTR','TY'])
赋予我们
{'E': {'W': {'Q': {}},
'Y': {'T': {}}},
'Q': {'Q': {'Q': {'Q': {}}}},
'R': {'T': {'Y': {}}},
'Y': {'T': {}}}
如果您想返回匹配的后缀,那只是跟踪我们尝试降级时看到的字符的问题。
def has_suffix(trie, s):
if not trie:
return ''
letters = []
for c in reversed(s):
try:
trie = trie[c]
letters.append(c)
except KeyError:
return None
if not trie:
return ''.join(letters)
return None
值得注意的是,build_trie([''])
和build_trie([])
都可以到达空的特里字符串,并在所有字符串的末尾匹配空字符串。为避免这种情况,您可以检查suffixes
的长度并返回一些非dict值,该值将在has_suffix
中进行检查