Julia使用推导式替换嵌套for循环报j未定义错误问题咨询
错误原因
你的推导式作用域顺序写反了:if ismissing(dfc[j,i]) 是绑定在最外层遍历i的循环上的,这时候内层循环的迭代变量j还没被声明定义,外层作用域访问不到j,所以直接抛出未定义变量错误。
另外你现在的写法用两层方括号嵌套推导式,会生成两层无意义的临时数组,推导式本身是用来构造收集结果的,用来做push!这种副作用操作本身就不是推荐写法,后续维护可读性很差。
解决方法
按简洁度从高到低给你几个可直接运行的实现:
- 方法1:用正确顺序的推导式直接收集结果,不需要提前初始化空向量
# 先遍历所有列i,再遍历对应列的所有行j,遇到缺失值就记录行号j,最后去重避免同一行多列缺失重复记录 empty_rows = unique([j for i in 1:ncol(dfc) for j in 1:nrow(dfc) if ismissing(dfc[j, i])])
注:这里直接用ncol(dfc)、nrow(dfc)取DataFrame的行列数,比硬写8、12更鲁棒,后续你改dfc的尺寸也不用改代码。
- 方法2:保留你预定义空向量+push!的逻辑,用显式循环写(比硬套推导式可读性高很多)
empty_rows = Int64[] # Julia支持for循环写多迭代器,直接把两层循环写在同一行 for i in 1:ncol(dfc), j in 1:nrow(dfc) ismissing(dfc[j, i]) && push!(empty_rows, j) end unique!(empty_rows)
- 方法3:用DataFrames原生API,完全不用手写循环
# 直接找出所有包含至少一个缺失值的行索引 empty_rows = findall(row -> any(ismissing, row), eachrow(dfc))
原写法的修正版(不推荐,仅帮你理解作用域问题)
如果硬要套你原来的嵌套推导式写法,需要把if条件放到j所在的内层循环作用域里,同时去掉多余的嵌套括号:
empty_rows = Int64[] [push!(empty_rows, j) for i in 1:8 for j in 1:12 if ismissing(dfc[j,i])] unique!(empty_rows)
这个写法虽然能跑,但推导式会返回一个和empty_rows内容一样的无用向量,浪费内存,非常不建议在生产代码里这么写。
内容的提问来源于stack exchange,提问作者Juergen D
相关产品推荐
相关产品推荐

