匹配一个没有空格的字符串,如果它包含单词列表中的单词

时间:2017-05-23 05:56:24

标签: python string algorithm python-3.x

我有一个存储在列表中的单词列表:

[
    'investment',
    'property',
    'something',
    'else',
    'vest'
]

我也有一个字符串列表,如此

[
    'investmentproperty',
    'investmentsomethingproperty',
    'investmentsomethingelseproperty',
    'abcinvestmentproperty',
    'investmentabcproperty'
]

鉴于这个单词列表和字符串列表,我需要确定哪些字符串包含单词列表中的单词,并且这些单词的最大数量。

在上面的例子中,如果单词的最大数量是3,那么只有字符串列表中的前两个项目才会匹配(即使' vest'是'投资&# 39;

这个例子简化了单词列表和字符串列表 - 实际上有数千个单词和数十万个字符串。所以这需要高效。所有字符串都不包含空格。

我试过像这样构建一个正则表达式:

^(?:(word1)|(word2)|(word3)){1,3}$

但是对于单词列表中的单词数量(目前为10,000),这种情况很慢。

由于

3 个答案:

答案 0 :(得分:0)

我认为这是你除了

代码:

strings = [
    'investmentproperty',
    'investmentsomethingproperty',
    'investmentsomethingelseproperty',
    'abcinvestmentproperty',
    'investmentabcproperty'
]
words = [
    'investment',
    'property',
    'something',
    'else'
]
new_words =filter(lambda x: [x for i in words if x in i and x != i] == [], words)
res = list()
for string in strings:
    len_string = len(string)
    in_words = []
    for w in new_words:
        if w in string:
            in_words.append(w)
    if len(''.join(in_words)) == len_string:
        res.append(string)
print res

输出:

['investmentproperty', 'investmentsomethingproperty', 'investmentsomethingelseproperty']

答案 1 :(得分:0)

如果我的两分钱很重要,我会将包含您正在寻找的关键词的列表转换为字典,这样您就不必继续迭代两个列表。

我忘了看看this Aho-Corasick算法,这可能对你很有帮助

如果不感兴趣,请按照以下

1-如果您想保留两个列表here

matchers = ['investment', 'property', 'something', 'else', 'vest']
matching = [s for s in my_list if any(xs in s for xs in matchers)]

2-或者

reduce((lambda x, y: x+len(filter((lambda z, x=y: z == x), list2))), list1, 0)

3- this听起来也非常有趣,看起来像是正则表达式的一个很好的替代品

对于限制匹配数量的其他要求,也许你可以添加一个在达到匹配数时中断的while循环。如果字典将您尝试查找的单词设置为键并将其所有值设置为1,则每次找到单词时都会添加值,直到达到目标为止。

答案 2 :(得分:0)

您期待多长时间?我测试了以下代码:

_list = ['investmentproperty'] * 100000
_dict = [
    'investment',
    'property',
    'something',
    'else'
] * 1000
regex = re.compile("^(?:" + "|".join(_dict) + "){1,3}$")

for i in _list:
    result = regex.match(i)
#cost 5.06s

for i in _list:
    result = re.match("^(?:" + "|".join(_dict) + "){1,3}$", i)
#cost 11.04s

我认为有100000长度列表和4000长度字典,这不是一个糟糕的表现,对吧?