[英]Python unpacking from list comprehension over empty input
When working with a function that returns multiple values with a tuple, I will often find myself using the following idiom to unpack the results from inside a list comprehension. 当使用一个使用元组返回多个值的函数时,我经常会发现自己使用以下习惯来从列表解析中解压缩结果。
fiz, buz = zip(*[f(x) for x in input])
Most of the time this works fine, but it throws a ValueError: need more than 0 values to unpack
if input
is empty. 大部分时间这种方法都可以正常工作,但它会抛出一个ValueError: need more than 0 values to unpack
如果input
为空,则ValueError: need more than 0 values to unpack
。 The two ways I can think of to get around this are 我能想到的两种解决方法是
fiz = []
buz = []
for x in input:
a, b = f(x)
fiz.append(a)
buz.append(b)
and 和
if input:
fiz, buz = zip(*[f(x) for x in input])
else:
fiz, buz = [], []
but neither of these feels especially Pythonic—the former is overly verbose and the latter doesn't work if input is a generator rather than a list (in addition to requiring an if/else where I feel like one really shouldn't be needed). 但是这些都不是特别感觉Pythonic - 前者过于冗长而后者如果输入是生成器而不是列表则不起作用(除了要求if / else,我觉得真的不需要) 。
Is there a good simple way to do this? 有一个很好的简单方法吗? I've mostly been working in Python 2.7 recently, but would also be interested in knowing any Python 3 solutions if they are different. 我最近一直在Python 2.7中工作,但如果它们不同,也会对了解任何Python 3解决方案感兴趣。
If f = lambda x: (x,x**2)
then this works 如果f = lambda x: (x,x**2)
则可行
x,y = zip(*map(f,input)) if len(input) else ((),())
If input=[]
, x=() and y=()
. 如果input=[]
,则x=() and y=()
。
If input=[2]
, x=(2,) and y=(4,)
如果input=[2]
,则x=(2,) and y=(4,)
If input=[2,3]
, x=(2,3) and y=(4,9)
如果input=[2,3]
,则x=(2,3) and y=(4,9)
They're tuples (not lists), but thats thats pretty easy to change. 它们是元组(不是列表),但那很容易改变。
I would consider using collections.namedtuple()
for this sort of thing. 我会考虑使用collections.namedtuple()
来做这类事情。 I believe the named tuples are deemed more pythonic, and should avoid the need for complicated list comprehensions and zipping / unpacking. 我相信命名的元组被认为更加pythonic,应该避免复杂的列表推导和压缩/解包。
From the documentation : 从文档 :
>>> p = Point(11, y=22) # instantiate with positional or keyword arguments
>>> p[0] + p[1] # indexable like the plain tuple (11, 22)
33
>>> x, y = p # unpack like a regular tuple
>>> x, y
(11, 22)
>>> p.x + p.y # fields also accessible by name
33
>>> p # readable __repr__ with a name=value style
Point(x=11, y=22)
You could use: 你可以使用:
fiz = []
buz = []
results = [fiz, buz]
for x in input:
list(map(lambda res, val: res.append(val), results, f(x)))
print(results)
Note about list(map(...)): in Python3, map returns a generator, so we must use it if we want the lambda to be executed.list does it. 关于list(map(...))的注意事项:在Python3中,map返回一个生成器,所以如果我们想要执行lambda,我们必须使用它。
(adapted from my answer to Pythonic way to append output of function to several lists , where you could find other ideas.) (改编自我对Pythonic的回答方法,将函数输出附加到几个列表 ,在那里你可以找到其他的想法。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.