Python正则报错TypeError:期望字符串/字节对象,求函数修正方案
我来帮你排查并修复这个函数的问题~
先分析你遇到的错误原因
你碰到的TypeError: expected string or bytes-like object主要来自这几个问题:
- 变量名不匹配:函数参数是
list_of_tuples,但列表推导里误用了未定义的tuples_with_keyword_posts,这会引发未定义错误;更关键的是后续处理嵌套列表时,把列表当成了字符串传入正则匹配。 - 正则表达式逻辑错误:
price_re用了^和$,会匹配整个包含价格的字符串而非提取价格本身;number_re只匹配带小数点的数字,漏掉了整数(比如示例里的4)。 - 嵌套列表处理失误:
[re.findall(price_re, post) for post in posts]会生成嵌套列表,后续filter处理时传入的是列表而非字符串,直接触发类型错误。 - 未处理非字符串元素:如果你的
posts里有空列表或非字符串值(比如你输入示例里的格式错误),也会触发类型错误。
修改后的函数(带详细注释)
import re def collect_keyterms(list_of_tuples): # 正则1:提取带货币符号的价格(只取价格本身,不是整个字符串) price_pattern = re.compile(r'[\$\£\€]\s?\d{1,3}(?:[.,]\d{3})*(?:[.,]\d{1,2})?') # 正则2:提取无货币符号的数字(用负向断言排除价格里的数字,避免重复提取) number_pattern = re.compile(r'(?<!\$|\£|\€)\b\d+(?:[.,]\d{1,2})?\b') processed_results = [] for keyword, posts in list_of_tuples: collected_prices = [] collected_numbers = [] for post in posts: # 跳过非字符串元素,彻底避免TypeError if not isinstance(post, str): continue # 提取当前文本里所有符合要求的价格和数字,合并到总列表 collected_prices.extend(price_pattern.findall(post)) collected_numbers.extend(number_pattern.findall(post)) # 过滤掉可能的空字符串(正则匹配一般不会产生,但做个保险) cleaned_prices = [p for p in collected_prices if p.strip()] cleaned_numbers = [n for n in collected_numbers if n.strip()] # 添加到结果(即使某个列表为空也保留,符合你的期望输出) processed_results.append((keyword, cleaned_prices, cleaned_numbers)) # 可选:如果要删除【价格和数字都为空】的元组,取消下面注释 # processed_results = [item for item in processed_results if item[1] or item[2]] return processed_results
测试示例(先修正你输入的格式错误)
你的原输入格式有误,应该是每个元组的第二个元素是字符串列表而非嵌套列表,修正后测试:
beginning = [ ('keyword1', ['', '', '$5', 'This has $6.50', 'this has 4']), ('keyword2', ['', '', '', '', '', '5.5']) ] # 调用函数 final_output = collect_keyterms(beginning) print(final_output) # 输出正好符合你的期望: # [('keyword1', ['$5', '$6.50'], ['4']), ('keyword2', [], ['5.5'])]
优化点说明
- 修复了变量名不一致的问题
- 调整正则逻辑,精准提取目标内容,避免无效匹配
- 用
extend替代嵌套列表推导,直接生成一维列表,避免后续处理出错 - 增加非字符串判断,彻底杜绝类型错误
- 保留空列表的同时,过滤掉无意义的空字符串
内容的提问来源于stack exchange,提问作者JRR
相关产品推荐
相关产品推荐

