列表推导式中itertools groupby对象的if判断始终为假问题排查
问题描述
现有一组文件名结构为[output-input]_[A-Z]_foo_bar_[0-n].pkl的文件列表:
file_list = [ 'output_A_foo_bar_0.pkl', 'output_A_foo_bar_1.pkl', 'output_A_foo_bar_2.pkl', 'output_A_foo_bar_3.pkl', 'output_B_foo_bar_0.pkl', 'output_B_foo_bar_1.pkl', 'output_B_foo_bar_2.pkl', 'output_B_foo_bar_3.pkl', 'output_G_foo_bar_1.pkl', 'output_H_foo_bar_0.pkl', 'output_H_foo_bar_1.pkl', 'input_A_foo_bar_0.pkl', 'input_H_foo_bar_0.pkl', 'input_H_foo_bar_1.pkl', 'input_H_foo_bar_2.pkl', 'input_H_foo_bar_3.pkl']
需求是筛选出以output开头且分组后包含4个元素的文件组,预期结果如下:
[['output_A_foo_bar_0.pkl', 'output_A_foo_bar_1.pkl', 'output_A_foo_bar_2.pkl', 'output_A_foo_bar_3.pkl'], ['output_B_foo_bar_0.pkl', 'output_B_foo_bar_1.pkl', 'output_B_foo_bar_2.pkl', 'output_B_foo_bar_3.pkl'] ]
尝试用itertools.groupby的列表推导式实现时,始终得到[[],[]]的结果,分组判断条件一直为False,无法得到正确输出。
问题根源
你遇到的问题核心在于itertools.groupby的特性:
groupby返回的分组对象是一次性迭代器,如果在判断条件(比如len(list(group)))中先遍历了迭代器,后续再将其转换为列表时,迭代器已经被耗尽,只能得到空数组。这就是你得到[[],[]]的直接原因。- 若分组key的提取逻辑不正确,会导致分组混乱,无法正确聚合同组文件。
正确实现方案
方案1:修正groupby的使用逻辑
先过滤出所有output开头的文件,再按统一的key分组,注意要先将分组迭代器转换为列表再进行长度判断:
from itertools import groupby # 第一步:过滤所有output开头的文件 output_files = [f for f in file_list if f.startswith('output_')] # 定义分组key:提取`output_[A-Z]`部分作为分组标识 def get_group_key(filename): # 按下划线拆分文件名,取前两部分拼接(如"output_A_foo..." → "output_A") return '_'.join(filename.split('_')[:2]) # 注意:如果原列表中同组文件不连续,必须先按分组key排序,否则groupby会拆分同组文件 output_files_sorted = sorted(output_files, key=get_group_key) # 分组并筛选长度为4的组 result = [] for key, group in groupby(output_files_sorted, key=get_group_key): group_files = list(group) # 先将迭代器转为列表,避免后续耗尽 if len(group_files) == 4: result.append(group_files)
方案2:用字典手动分组(更直观,无迭代器陷阱)
如果觉得groupby的迭代器特性容易踩坑,可以用字典手动聚合同组文件:
group_dict = {} for filename in file_list: # 跳过非output开头的文件 if not filename.startswith('output_'): continue # 提取分组key group_key = '_'.join(filename.split('_')[:2]) # 聚合同组文件 if group_key not in group_dict: group_dict[group_key] = [] group_dict[group_key].append(filename) # 筛选出长度为4的文件组 result = [files for files in group_dict.values() if len(files) == 4]
两种方案最终都能得到你需要的预期结果。
内容的提问来源于stack exchange,提问作者aren
相关产品推荐
相关产品推荐

