如何通过单个列表推导式为多个列表赋值?语法报错求助
如何用单个表达式同时为多个列表赋值
嘿,我懂你想简化代码的心情!你之前尝试的写法之所以报错,是因为误解了列表推导式的输出形式:
- 你写的
[item.km, item.price for item in data]会生成一个交替包含km和price值的扁平列表(比如[22899.0, 7990.0, 48235.0, 6900.0,...]),直接赋值给xs, ys时,Python会试图把这个长列表拆成两个元素,长度不匹配自然报错。 - 另一种写法
[km, price for km, price in data]生成的是元组组成的列表(比如[(22899.0,7990.0), (48235.0,6900.0),...]),同样没法直接拆成两个独立列表。
那正确的做法是什么呢?我们可以用zip(*...)配合生成器表达式实现“一次性拆分赋值”,具体代码如下:
from collections import namedtuple # 模拟你的数据结构 mileage = namedtuple('mileage', ['km', 'price']) data = [ mileage(km=22899.0, price=7990.0), mileage(km=48235.0, price=6900.0) ] # 核心写法:生成器输出(km, price)元组,zip(*)转置拆分 xs, ys = zip(*((item.km, item.price) for item in data)) # 若需要列表而非元组,转换一下即可 xs = list(xs) ys = list(ys) print(xs) # [22899.0, 48235.0] print(ys) # [7990.0, 6900.0]
原理拆解
(item.km, item.price) for item in data是生成器表达式,会逐个输出每个mileage对象的km和price组成的元组。zip(*...)里的*是解包操作符,它会把生成器的所有元组“展开”,zip则会把所有元组的第一个元素、第二个元素分别收集成两个元组,正好对应我们需要的km列表和price列表。- 如果想把转列表的操作也整合到一行,可以这么写:
xs, ys = [list(col) for col in zip(*((item.km, item.price) for item in data))]
这样就用单个组合式实现了同时为两个列表赋值,比写两个独立的列表推导式更简洁!
内容的提问来源于stack exchange,提问作者IMCoins
相关产品推荐
相关产品推荐

