1

我想做一个 if 语句来检测是否可以按顺序用列表中的项目形成一个字符串。例如,如果我想检查一个术语是否与“HelloWorld”具有相同的含义,我将有一个带有 的“hello”列表['hello', 'Hello', 'Hi', 'Greetings', 'Hola']和一个带有 的“world”列表['world', 'World', 'Planet', 'Earth']。然后,检查一个字符串是否等于“hello”列表中的任何项目,后跟“world”列表中的任何项目。“HelloWorld”、“GreetingsEarth”和“HiPlanet”都会成功触发 if 语句。我该怎么做?我想使用 Python 列表,所以正则表达式 (a|b) 似乎不切实际。

4

4 回答 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 回答