Python列表推导式中if与if-else的位置规则差异及报错原因
Python列表推导式中if的两种用法差异
列表推导式里的if分属完全不同的两种语法结构,位置不能随意调换:
- 位于
for关键字前的if-else属于三元值表达式
这个结构的作用是计算当前迭代位置要存入列表的具体值,语法强制要求必须写全返回值A if 判断条件 else 返回值B的完整结构,不能缺失else分支——毕竟不管条件是否成立,都必须有一个确定的值存入结果列表,没有else的话条件不成立时就无值可放,会直接触发语法错误。
正确示例b就符合这个规则:a = [1,2,3] b = [i if i%2 else i+1 for i in a] # 运行结果b为[1,3,3],奇数保留原值,偶数+1后存入,所有元素都保留 - 位于
for关键字后的if属于迭代筛选条件
这个结构的作用是判断当前迭代的元素要不要保留进最终结果,不需要搭配else:条件成立就保留当前元素、计算值后存入列表;条件不成立就直接跳过当前元素,根本不需要计算对应值,自然不需要else分支。
示例d就属于这类用法:d = [i for i in a if i%2] # 运行结果d为[1,3],只保留奇数,偶数直接被过滤掉
写法c无法运行的原因
错误示例c代码如下:
c = [i if i%2 for i in a else i+1]
报错的核心原因是完全打乱了两类if的语法规则:
- 在for前面的值表达式位置,只写了半段三元结构
i if i%2,缺失了语法强制要求的else分支,解析到这里就会触发语法错误; - 把else写在了for后面的筛选条件位置,这个语法位仅支持写不带else的筛选判断,Python解析器根本不认识出现在这里的else关键字,会直接抛出语法异常。
快速记忆技巧:要对所有元素做值转换、不丢元素,就把带完整if-else的三元表达式写在for前面;要过滤掉部分元素、不满足条件的直接丢弃,就把不带else的筛选if写在for后面。
内容的提问来源于stack exchange,提问作者wgt
相关产品推荐
相关产品推荐

