Python字典推导式内eval执行报NameError: df未定义问题
问题根因
Python 3中字典推导式、列表推导式会生成独立的嵌套作用域,eval()执行时默认的变量查找逻辑无法穿透推导式的独立作用域,读取到外层函数内定义的局部变量df,因此抛出名称错误。直接在函数非推导式代码块中执行eval()时,作用域和df所在的函数局部作用域一致,所以能正常运行。
适配要求的实现方案
以下实现完全满足约束:保留全局变量df1、不使用序号作为规则键、新增列标识每行未选中原因,同时解决作用域报错问题:
import pandas as pd # 全局业务必需变量df1保留,不做修改 df1 = pd.DataFrame({ 'Name':['JOHN','ALLEN','BOB','NIKI','CHARLIE','CHANG'], 'Age':[35,42,63,29,47,51], 'Salary_in_1000':[100,93,78,120,64,115], 'FT_Team':['STEELERS','SEAHAWKS','FALCONS','FALCONS','PATRIOTS','STEELERS'] }) def select_func(df): df = df.copy() # 自定义筛选规则列表,后续直接用规则字符串作为标识键 rules = [ "df['Age'] < 60", "df['Salary_in_1000'] >= 80" ] # 核心修复:给eval显式传入全局+当前局部命名空间,推导式场景下也能找到df变量 rule_res = { rule: eval(rule, globals(), locals()) for rule in rules } # 新增列记录每行未命中的规则原因 df['unmatched_reason'] = '' for rule_str, match_mask in rule_res.items(): df.loc[~match_mask, 'unmatched_reason'] += f"未满足: {rule_str}; " return df # 测试调用 result_df = select_func(df1) print(result_df)
关键说明
- 给
eval()传入globals()保证全局业务变量(比如df1)可以被正常访问,传入locals()保证函数内的入参df可以在推导式的独立作用域中被找到,从根源解决NameError。 - 字典键直接使用原始规则字符串,不需要生成n0、n1这类无意义序号,规则和结果一一对应可读性更强。
- 遍历所有规则的布尔匹配结果,将不满足的规则拼接后写入
unmatched_reason列,直接可以查看每行被过滤的具体原因。
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

