3

我有一个字符串(例如:)"alpha beta charlie, delta&epsilon foxtrot"和一个列表(例如["zero","omega virginia","apple beta charlie"])。有没有一种方便的方法来遍历字符串中的每个单词和单词组合以便在列表中搜索它?

4

1 回答 1

6

目的

您说的是组合,但组合在语义上是无序的,您的意思是,您打算找到由空格连接的所有有序排列与目标列表的交集。

首先,我们需要导入我们打算使用的库。

import re
import itertools

拆分字符串

不要拆分字符,您正在对不包括奇怪字符的单词进行语义搜索。由re模块提供支持的正则表达式非常适合这一点。在原始 Python 字符串中r'',我们使用正则表达式来表示单词的边缘,围绕任何大于或等于一的数字的\b字母数字字符(和_),。\w+

re.findall返回每个匹配项的列表。

re_pattern = r'\b\w+\b'
silly_string = 'alpha beta charlie, delta&epsilon foxtrot'
words = re.findall(re_pattern, silly_string)

在这里,words 是我们的单词表:

>>> print words
['alpha', 'beta', 'charlie', 'delta', 'epsilon', 'foxtrot']

创建排列

继续,我们更喜欢使用生成器来操作我们的数据,以避免在我们需要之前不必要地物化数据并将大型数据集保存在内存中。itertools 库有一些很好的函数,可以很好地满足我们提供上述单词的所有排列并将它们链接到单个迭代中的需求:

_gen = (itertools.permutations(words, i + 1) for i in xrange(len(words)))
all_permutations_gen = itertools.chain(*_gen)

列出 all_permutations_genlist(all_permutations_gen)会给我们:

[('alpha',), ('beta',), ('charlie',), ('delta',), ('epsilon',), ('foxtrot',), ('alpha', 'beta '), ('alpha', 'charlie'), ('alpha', 'delta'), ('alpha', 'epsilon'), ('alpha', 'foxtrot'), ('beta', 'alpha '), ('beta', 'charlie'), ('beta', 'delta'), ('beta', 'epsilon'), ('beta', 'foxtrot'), ('charlie', 'alpha '), ('charlie', 'beta'), ('charlie', 'delta'), ('charlie', 'epsilon'), ('charlie', 'foxtrot'), ('delta', 'alpha '), ('delta', 'beta'), ('delta', 'charlie'), ('delta', 'epsilon'), ('delta', 'foxtrot'), ('epsilon', 'alpha'), ('epsilon', 'beta'), ('epsilon', 'charlie'), ('epsilon', 'delta'), (' epsilon', 'foxtrot'), ('foxtrot', 'alpha'), ('foxtrot', 'beta'), ('foxtrot', 'charlie'), ('foxtrot', 'delta'), ('狐步舞', 'epsilon'), ('alpha', 'beta', 'charlie'), ('alpha', 'beta', 'delta'), ...charlie'), ('foxtrot', 'delta'), ('foxtrot', 'epsilon'), ('alpha', 'beta', 'charlie'), ('alpha', 'beta', 'delta' ), ...charlie'), ('foxtrot', 'delta'), ('foxtrot', 'epsilon'), ('alpha', 'beta', 'charlie'), ('alpha', 'beta', 'delta' ), ...

如果我们将生成器具体化为列表而不是集合,打印前 20 个项目将显示:

>>> print all_permutations[:20] # this only works if you cast as a list instead
['alpha', 'beta', 'charlie', 'delta', 'epsilon', 'foxtrot', 'alpha beta', 'alpha charlie', 'alpha delta', 'alpha epsilon', 'alpha foxtrot', 'beta alpha', 'beta charlie', 'beta delta', 'beta epsilon', 'beta foxtrot', 'charlie alpha', 'charlie beta', 'charlie delta', 'charlie epsilon']

但这会在我们准备好之前耗尽发电机。因此,现在我们得到了这些单词的所有排列的集合

all_permutations = set(' '.join(i) for i in all_permutations_gen)

检查目标列表中任何排列的成员资格

所以我们看到,我们现在可以搜索与目标列表的交集:

>>> target_list = ["zero","omega virginia","apple beta charlie"]
>>> all_permutations.intersection(target_list)
set([])

在这种情况下,对于给出的示例,我们得到空集,但是如果我们的排列集中的目标中有一个字符串:

>>> target_list_2 = ["apple beta charlie", "foxtrot alpha beta charlie"]
>>> all_permutations.intersection(target_list_2)
set(['foxtrot alpha beta charlie'])
于 2014-01-03T07:36:11.500 回答