简体   繁体   English

Python从列表理解中解压缩空输入

[英]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.

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