繁体   English   中英

列表理解的多重分配

[英]Multiple assignation with list comprehension

我想知道是否可以通过一个列表理解来分配多个列表。 我以某种方式无法理解语法。

所以,不要做...

xs = [item.km for item in data]
ys = [item.price for item in data]

我想做...

xs, ys = [km, price for km, price in data]
# or...
xs, ys = [item.km, item.price for item in data]

但这会引发语法错误,而且我似乎找不到该错误。

即使看起来很明显,数据也如下...

for elem in data:
    print elem
# outputs (this is a namedtuple) :
# mileage(km=22899.0, price=7990.0)
# mileage(km=48235.0, price=6900.0)
# mileage(km=54000.0, price=7990.0)
# mileage(km=60949.0, price=7490.0)
...

如果我正确理解您的结构,则需要带星号的zip()来转置数据:

xs, ys = zip(*[(km, price) for km, price in data]) 

单个列表理解产生单个列表。 您尝试使用多重分配将结构[(a,b), (a,b), (a,b)]分配给两个变量,但这不起作用,因为条目数不匹配。 您可以改为生成对组件的列表:

kms = [item.km for item in data]
prices = [item.price for item in data]

但这确实会两次处理列表data 如果真的要避免这种情况很重要,我们可以并行构建两个列表,但这仍然不是一个完整的理解:

kms, prices = [], []
for item in data:
    kms.append(item.km)
    prices.append(item.price)

通过预分配列表,可以减轻内存管理器的负担:

kms, prices = [None]*len(data), [None]*len(data)
for i,item in enumerate(data):
    kms[i]=item.km
    prices[i]=item.price

但是最有可能的情况是,最好使用numpy或pandas联合处理数据。

可以使用fold来产生两个列表,并从一个理解中获得输入,但是在常见的Python实现中既复杂又效率低下。

就像其他人已经指出的那样,简单的答案是: 列表理解产生单个列表

但是,您可以按照@Chris_Rands的建议,使用zip转换数据。 我会对其进行调整,并使用生成器使其更快一些。

xs, ys = zip(*((item.km, item.price) for item in data))

问题在于,上面的代码将对数据集进行多次迭代,以产生所需的结果。 由于Yann的答案指出(使用答案甚至更好),因此使用平原for迭代的效果要好得多:

xs, ys = [], []
for item in data:
    xs.append(item.km)
    ys.append(item.price)

有时我们需要牺牲一些东西来提高性能。 在这种情况下:

  • zip是一个很棒的工具,但它并不完全适用于此。 这片段是不是人们不知道用例的简单易读,而且也慢(O(2 * N ^ 2)或可能为O(n ^ 2)与发电机,我还没有测试)。
  • 使用plain for将使您的代码真正更快(O(n)),这取决于data的大小可能真的很重要。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM