You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python列表推导式中执行多个表达式?(附循环转推导需求)

如何将带状态修改的for循环转为Python列表推导式

原需求代码

需要将以下for循环转换为列表推导式:

number = 10
deci_list = []

for i in sorted(list(range(9)), reverse=True):
    if 2**i <= number:
        deci_list.append(1)
        number -= 2**i
    else:
        deci_list.append(0)

尝试与错误

尝试的代码因在列表推导式的if-else表达式中加入赋值语句触发语法错误:

thing = sorted(list(range(9)), reverse=True)
new_thing = ['1' if 2**i <= number number -= 2**i else '0' for i in thing]

报错信息:

new_thing = ['1' if 2**i <= number number -= 2**i else '0' for i in thing]
                 ^^^^^^^^^^^^^^^^^^^^^
SyntaxError: expected 'else' after 'if' expression

问题原因

列表推导式中的if-else是表达式,不是可执行的语句块,不能在其中执行赋值操作(number -= 2**i属于赋值语句,会修改外部变量状态)。这种带副作用的操作不仅语法不允许,还会让代码可读性变差,容易引发意外问题。

解决方案

方案1:用生成器函数模拟原逻辑(最接近原循环,可读性高)

把原循环逻辑封装成生成器,再转成列表:

def generate_binary_bits(num):
    for i in sorted(range(9), reverse=True):
        power = 2 ** i
        if power <= num:
            yield 1
            num -= power
        else:
            yield 0

number = 10
deci_list = list(generate_binary_bits(number))

方案2:位运算直接计算(更简洁,无副作用)

原代码本质是生成number的9位二进制表示(高位在前,不足补0),可以用位运算直接判断每一位:

number = 10
deci_list = [1 if (number & (1 << i)) else 0 for i in reversed(range(9))]

解释:1 << i等价于2**i,number & (1 << i)用来判断第i位是否为1;reversed(range(9))实现从8到0的遍历,和原循环的sorted(range(9), reverse=True)效果一致。

方案3:不推荐的列表推导式写法(带副作用)

如果非要用列表推导式,可以借助可变对象(比如列表)维护状态,但这种写法可读性极差,不建议使用:

number = [10]  # 用列表包装,因为列表是可变对象
deci_list = [
    1 if (2**i <= number[0]) and (number.__setitem__(0, number[0]-2**i) or True) 
    else 0 
    for i in sorted(range(9), reverse=True)
]

内容的提问来源于stack exchange,提问作者TheBoogeyMan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 18:45:49