Python字符串单词查找函数为何返回空列表?
问题分析:word_search函数返回空列表的原因及修复
问题场景
编写的word_search函数接收doc_list和keyword两个参数,目标是返回原字符串列表中包含指定关键词的元素索引列表(忽略大小写,逗号、句号不影响搜索),但运行后返回空列表。
预期示例
doc_list = ["The Learn Python Challenge Casino.", "They bought a car", "Casinoville"] >>> word_search(doc_list, 'casino') >>> [0] >>> word_search(doc_list, 'car') >>> [1]
用户代码
def word_search(doc_list, keyword): #remove periods and commas and set all to lowercase doc_list_lower = [elem.rstrip('.,').lower() for elem in doc_list] print(doc_list_lower) #make keyword lowercase keyword_lower = keyword.lower() #split string into list of words doc_list_lower_splitted = [elem.split() for elem in doc_list_lower] print(doc_list_lower_splitted) #return list of indexes of words which matched with keyword return [doc_list_lower_splitted.index(elem) for elem in doc_list_lower_splitted if keyword_lower in doc_list_lower_splitted] #check the function doc_list = ["The Learn Python Challenge Casino.", "They bought a car", "Casinoville"] word_search(doc_list, 'casino')
运行结果
['the learn python challenge casino', 'they bought a car', 'casinoville'] [['the', 'learn', 'python', 'challenge', 'casino'], ['they', 'bought', 'a', 'car'], ['casinoville']] []
错误原因
问题出在最后一行的判断逻辑:
if keyword_lower in doc_list_lower_splitted是检查关键词是否属于整个二维列表的元素(即是否是某个子列表本身),而非检查关键词是否在当前遍历的子列表(单篇文档的单词集合)中。- 以测试用例为例,
doc_list_lower_splitted是二维列表,'casino'是字符串,显然不是子列表,因此条件永远不成立,返回空列表。
另外,doc_list_lower_splitted.index(elem)存在潜在问题:如果列表中有重复的子列表,会返回第一个匹配项的索引,而非当前元素的真实索引。
修复后的代码
基础修复版
修正判断逻辑,使用enumerate直接获取元素索引,避免index方法的潜在问题:
def word_search(doc_list, keyword): # 处理每个文档:移除末尾标点并转小写 doc_list_lower = [elem.rstrip('.,').lower() for elem in doc_list] keyword_lower = keyword.lower() doc_splitted = [elem.split() for elem in doc_list_lower] # 遍历检查每个文档的单词列表,收集符合条件的索引 return [idx for idx, words in enumerate(doc_splitted) if keyword_lower in words] # 测试验证 doc_list = ["The Learn Python Challenge Casino.", "They bought a car", "Casinoville"] print(word_search(doc_list, 'casino')) # 输出 [0] print(word_search(doc_list, 'car')) # 输出 [1]
优化增强版
原代码的rstrip('.,')仅移除字符串末尾的标点,若标点出现在单词中间(比如"casino,")会处理失效,这里改用全局替换处理所有位置的标点:
def word_search(doc_list, keyword): keyword_lower = keyword.lower() result = [] for idx, doc in enumerate(doc_list): # 移除所有逗号、句号,转小写后拆分单词 processed_words = doc.replace(',', '').replace('.', '').lower().split() if keyword_lower in processed_words: result.append(idx) return result # 测试验证 doc_list = ["The Learn Python Challenge Casino.", "They bought a car", "Casinoville", "I love casino, too"] print(word_search(doc_list, 'casino')) # 输出 [0, 3]
内容的提问来源于stack exchange,提问作者charly99
相关产品推荐
相关产品推荐

