Python for循环遍历字符串时if条件满足却未生效问题
问题根因
筛选条件逻辑错误的核心原因是对Python中str.find()方法的返回值、以及Python隐式布尔转换规则理解有误:
str.find(子串)的返回规则:子串不存在时返回-1;子串存在时返回子串第一次出现的起始索引(从0开始的非负整数)- Python隐式布尔转换规则:整数做布尔判断时,仅
0会被判定为False,其余所有非零整数(包括负数-1)都会被判定为True
你直接将find()的返回值作为判断条件,实际逻辑和预期完全不符:
- 当路径中不存在目标子串时,
find()返回-1,会被判定为True - 只有当目标子串刚好出现在路径最开头(返回索引
0)时,才会被判定为False
这就导致第一个完全不包含csv_store、03-06-2022的路径,也满足了判断条件被加入结果列表。
修正方案
推荐写法(语义最清晰)
日常判断字符串是否包含子串,优先直接用in关键字,不需要手动调用find(),可以从根源上避免隐式转换的逻辑bug:
absolute_path_list = [] f = [ 'Documents/projects/packout_model/.venv/lib/python3.9/site-packages/numpy/core/tests/data/file1.csv', 'Documents/projects/packout_model/data/03-06-2022/csv_store/file2.csv', '/Documents/projects/packout_model/data/03-06-2022/csv_store/file3.csv'] for file in f: if 'csv_store' in file and '03-06-2022' in file and 'packout_model' in file and file.endswith("csv"): absolute_path_list.append(file) print(absolute_path_list)
运行后输出结果和预期完全一致:
['Documents/projects/packout_model/data/03-06-2022/csv_store/file2.csv', '/Documents/projects/packout_model/data/03-06-2022/csv_store/file3.csv']
自定义判断函数写法
如果你习惯封装find()的判断逻辑,可以显式判断返回值是否为-1,不要依赖隐式布尔转换:
def check_found(val: str=None, substring: str=None): return not val.find(substring) == -1 # .find返回-1代表未找到对应子串 for file in f: print(check_found(file, 'csv_store')) # 输出结果 False True True
注意:尽量不要在条件判断中依赖隐式类型转换,写显式的判断逻辑能减少大部分低级逻辑bug
内容的提问来源于stack exchange,提问作者user4933
相关产品推荐
相关产品推荐

