我想做一个 if 语句来检测是否可以按顺序用列表中的项目形成一个字符串。例如,如果我想检查一个术语是否与“HelloWorld”具有相同的含义,我将有一个带有 的“hello”列表['hello', 'Hello', 'Hi', 'Greetings', 'Hola']
和一个带有 的“world”列表['world', 'World', 'Planet', 'Earth']
。然后,检查一个字符串是否等于“hello”列表中的任何项目,后跟“world”列表中的任何项目。“HelloWorld”、“GreetingsEarth”和“HiPlanet”都会成功触发 if 语句。我该怎么做?我想使用 Python 列表,所以正则表达式 (a|b) 似乎不切实际。
问问题
1012 次
4 回答
4
如果要避免使用正则表达式,可以使用生成器表达式来测试每个组合(通过 生成itertools.product
):
import itertools
combinations = (''.join((first, second)) for first, second in itertools.product(a, b))
any('HelloWorld' == combination for combination in combinations)
请注意,这比正则表达式方法慢得多,尤其是在遇到最坏情况(不匹配)时:
>>> timeit.timeit('search("HelloWorld"); search("HiThere")', 'from __main__ import reMatch as search')
1.8922290802001953
>>> timeit.timeit('search("HelloWorld"); search("HiThere")', 'from __main__ import genMatch as search')
18.3697190284729
生成器表达式比正则表达式方法慢 10 倍。
(我使用re.compile()
编译的正则表达式进行测试)。
于 2012-09-22T18:41:32.547 回答
2
正则表达式可以正常工作:
a = ['hello', 'Hello', 'Hi', 'Greetings', 'Hola']
b = ['world', 'World', 'Planet', 'Earth']
import re
r = '^(%s)(%s)$' % ('|'.join(a), '|'.join(b))
print re.match(r, "HelloWorld").groups() # ('Hello', 'World')
print re.match(r, "HiThere") # None
非正则表达式解决方案很乏味:
s = "GreetingsEarth"
for x in a:
if s.startswith(x) and s[len(x):] in b:
print x, '+', s[len(x):]
break
于 2012-09-22T18:36:42.383 回答
2
这实际上可以使用正则表达式来完成,如下所示:
list1 = ['hello', 'Hello', 'Hi', 'Greetings', 'Hola']
list2 = ['world', 'World', 'Planet', 'Earth']
regex = "(%s)(%s)" % ("|".join(list1), "|".join(list2))
print re.match(regex, "HelloWorld")
但这也可以通过以下方式完成itertools.product
:
print any("HelloWorld" == x + y for x, y in itertools.product(list1, list2))
于 2012-09-22T18:36:53.127 回答
1
我为第二个列表使用了一个集合,这样您就不必每次都遍历它的所有项目。
a = ['hello', 'Hello', 'Hi', 'Greetings', 'Hola']
b = ['world', 'World', 'Planet', 'Earth']
b_set = set(b)
needle = 'HelloWorld'
for start in a:
if needle.startswith(start) and needle[len(start):] in b_set:
print 'match'
如果您正在寻找更短的版本
any((needle[len(start):] in b_set for start in a if needle.startswith(start)))
与此相反,itertools.product
此解决方案不必比较所有n^2
可能的组合,而只需遍历第一个列表 ( n
) 并在最坏的情况下进行额外的集合查找。
于 2012-09-22T18:50:47.783 回答