检查元组是否存在于元组列表时触发ValueError的问题求助
问题根因
该报错为numpy数组参与布尔判断的典型触发场景:
纯Python原生list做相等比较、in判断不会触发该错误,只有当元组中嵌套的可迭代对象实际是numpy.ndarray类型时才会出现问题:
- 执行
x not in to_explode时,Python会遍历to_explode所有元素和x做==比较 - 若元组内嵌套了numpy数组,
numpy数组 == numpy数组返回的不是单个布尔值,而是逐元素比较得到的布尔数组 - Python需要将布尔数组转为单个布尔值判断相等性,就会抛出对应
ValueError
控制台运行正常、pytest运行报错的原因是:控制台测试时用的是原生Python列表构造的测试数据,而pytest脚本里concat_tuples的嵌套元素实际是numpy数组,之前校验类型时仅检查了外层的元组、列表类型,未检查嵌套元素的类型。
解决方案
方案1:自定义相等比较逻辑,兼容numpy数组
比较前统一将numpy数组转为原生Python列表再做判断:
import numpy as np def tuple_equals(a, b): if len(a) != len(b): return False for item_a, item_b in zip(a, b): if isinstance(item_a, np.ndarray): item_a = item_a.tolist() if isinstance(item_b, np.ndarray): item_b = item_b.tolist() if item_a != item_b: return False return True not_explode = [x for x in concat_tuples if not any(tuple_equals(x, e) for e in to_explode)]
方案2:用下标过滤,完全避免元素相等比较
生成to_explode时同步记录符合条件的下标,后续直接用下标过滤,从根源规避比较问题:
to_explode = [] to_explode_ids = set() for idx, c in enumerate(concat_tuples): # 判断条件兼容numpy数组类型 if any(isinstance(x, (list, np.ndarray)) and len(x) > 1 for x in c): to_explode.append(c) to_explode_ids.add(idx) not_explode = [x for idx, x in enumerate(concat_tuples) if idx not in to_explode_ids]
内容的提问来源于stack exchange,提问作者chatax
相关产品推荐
相关产品推荐

