[英]Multiple assignation with list comprehension
I am trying to know if I can assign multiple lists with one single list comprehension. 我想知道是否可以通过一个列表理解来分配多个列表。 I somehow can't get my mind around the syntax.
我以某种方式无法理解语法。
So, instead of doing... 所以,不要做...
xs = [item.km for item in data]
ys = [item.price for item in data]
I'd like to do... 我想做...
xs, ys = [km, price for km, price in data]
# or...
xs, ys = [item.km, item.price for item in data]
But this throws me a syntax error, and I can't seem to find the error. 但这会引发语法错误,而且我似乎找不到该错误。
Even if it seemed obvious, the data is as follow... 即使看起来很明显,数据也如下...
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 single list comprehension produces a single list. 单个列表理解产生单个列表。 You've tried to assign a list of the structure
[(a,b), (a,b), (a,b)]
to two variables using multiple assignment, and this doesn't work because the number of entries doesn't match. 您尝试使用多重分配将结构
[(a,b), (a,b), (a,b)]
分配给两个变量,但这不起作用,因为条目数不匹配。 You could instead produce lists of the pair components: 您可以改为生成对组件的列表:
kms = [item.km for item in data]
prices = [item.price for item in data]
But this does process the list data
twice. 但这确实会两次处理列表
data
。 If it's really important to avoid this, we could build the two lists in parallel, but that still isn't a single comprehension: 如果真的要避免这种情况很重要,我们可以并行构建两个列表,但这仍然不是一个完整的理解:
kms, prices = [], []
for item in data:
kms.append(item.km)
prices.append(item.price)
You could achieve a lower load on the memory manager by preallocating the lists: 通过预分配列表,可以减轻内存管理器的负担:
kms, prices = [None]*len(data), [None]*len(data)
for i,item in enumerate(data):
kms[i]=item.km
prices[i]=item.price
But most likely you'd be better off processing the data in a joint manner using something like numpy or pandas. 但是最有可能的情况是,最好使用numpy或pandas联合处理数据。
It's possible to use a fold to produce two lists with input from one comprehension, but it's both complex and inefficient in common Python implementations. 可以使用fold来产生两个列表,并从一个理解中获得输入,但是在常见的Python实现中既复杂又效率低下。
Simple answer is, like others have pointed already: a list comprehension produces a single list . 就像其他人已经指出的那样,简单的答案是: 列表理解产生单个列表 。
You could, however, as @Chris_Rands suggested, transpose your data using zip
. 但是,您可以按照@Chris_Rands的建议,使用
zip
转换数据。 I would tweak it and use a generator to make it a little faster. 我会对其进行调整,并使用生成器使其更快一些。
xs, ys = zip(*((item.km, item.price) for item in data))
The problem is that the above will iterate multiple times over the data set in order to produce what you expect. 问题在于,上面的代码将对数据集进行多次迭代,以产生所需的结果。 Using a plain
for
iteration will perform far better, as Yann's answer states (that answer has an even better alternative): 由于Yann的答案指出(使用答案甚至更好),因此使用平原
for
迭代的效果要好得多:
xs, ys = [], []
for item in data:
xs.append(item.km)
ys.append(item.price)
Sometimes we need to sacrifice some things in favour of performance. 有时我们需要牺牲一些东西来提高性能。 And in this case:
在这种情况下:
zip
is an great tool, but it isn't exactly meant for that. zip
是一个很棒的工具,但它并不完全适用于此。 That snippet isn't easily readable for people unaware of the use case, and is also slow (O(2*n^2) or maybe O(n^2) with a generator, I haven't tested). for
will make your code really faster (O(n)), which may really matter depending on the size of data
. for
将使您的代码真正更快(O(n)),这取决于data
的大小可能真的很重要。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.