Python 文本搜索问题

3 投票
4 回答
583 浏览
提问于 2025-04-17 02:51

我想知道,如果你在Python中打开一个文本文件,然后想要搜索包含特定字母的单词,该怎么做。

比如说,你输入了6个不同的字母(a、b、c、d、e、f),你想要搜索的单词至少要包含3个字母。

每个字母在一个单词中只能出现一次,而且字母'a'必须得包含在内。

那么,这种特定的搜索代码应该怎么写呢?

4 个回答

0
words = 'fubar cadre obsequious xray'

def find_words(src, required=[], letters=[], min_match=3):
    required = set(required)
    letters = set(letters)

    words = ((word, set(word)) for word in src.split())
    words = (word for word in words if word[1].issuperset(required))
    words = (word for word in words if len(word[1].intersection(letters)) >= min_match)
    words = (word[0] for word in words)
    return words

w = find_words(words, required=['a'], letters=['a', 'b', 'c', 'd', 'e', 'f'])
print list(w)
from collections import Counter

def valid(word, letters, min_match):
    """At least min_match, no more than one of any letter"""
    c = 0
    count = Counter(word)
    for letter in letters:
        char_count = count.get(letter, 0)
        if char_count > 1:
            return False
        elif char_count == 1:
            c += 1
        if c == min_match:
            return True
    return True


def find_words(srcfile, required=[], letters=[], min_match=3):
    required = set(required)
    words = (word for word in srcfile.split())
    words = (word for word in words if set(word).issuperset(required))
    words = (word for word in words if valid(word, letters, min_match))
    return words

编辑 1:我也没有仔细阅读要求。要确保一个单词只包含一个有效字母的实例。

2

如果我要写这个,我会这样做:

我会写一个函数,这个函数接收一个单词,然后检查这个单词是否符合要求,最后返回一个真假值。

接着,我会写一些代码,逐个检查文件里的所有单词,把每个单词都传给这个函数,然后打印出那些函数返回True的单词。

3

让我们来看看……

return [x for x in document.split()
        if 'a' in x and sum((1 if y in 'abcdef' else 0 for y in x)) >= 3]

split这个函数如果不加任何参数,就像是一个“分词”功能,它会把字符串中的空白部分当作分隔符,把单词分开,并且会去掉那些没有字符的单词。接着,你要检查字母'a'是否在这个单词里。如果'a'在这个单词中,就会用一个生成器表达式去检查单词里的每一个字母。如果这个字母在可用字母的字符串里,就返回1,这样就可以加到总和里。否则就返回0。如果总和大于或等于3,就保留这个单词。这里用生成器而不是列表推导式是因为sum函数可以接受任何可迭代的对象,而且这样可以避免创建一个临时的列表(这样可以节省内存)。

不过,由于使用了in(在字符串中查找的时间复杂度是O(n)),所以访问速度不是最好,但这通常不是个大问题,除非数据集非常大。你可以稍微优化一下,把字符串放进一个集合里,而常量'abcdef'也可以很容易地变成一个集合。我只是觉得这样会破坏我之前的简洁写法。

补充:哦,为了提高if部分的效率(这部分是比较慢的),你可以把它单独写成一个函数,这样只需遍历一次字符串,如果条件满足就返回True。我本来想这么做,但这样会破坏我的简洁写法。

补充2:我没看到“必须有3个不同字符”的部分。这个条件在一行代码里是做不到的。你可以把if部分提取到一个函数里。

def is_valid(word, chars):
    count = 0
    for x in word:
        if x in chars:
            count += 1
            chars.remove(x)
    return count >= 3 and 'a' not in chars

def parse_document(document):
    return [x for x in document.split() if is_valid(x, set('abcdef'))]

这个方法在实际数据集上应该不会有性能问题。

撰写回答