Pythonic将函数输出附加到多个列表的方法

时间:2017-04-19 15:29:27

标签: python zip append temp

我有一个问题,我还没有找到一个好的解决方案。我正在寻找一种更好的方法来将函数输出附加到两个或更多列表,而不使用临时变量。示例如下:

def f():
  return 5,6

a,b = [], []
for i in range(10):
  tmp_a, tmp_b = f()
  a.append(tmp_a)
  b.append(temp_b)

我尝试过像zip(* f())这样的东西,但还没有找到解决办法。 任何方法去除那些临时变量都会非常有用,谢谢!

修改其他信息: 在这种情况下,函数的输出数总是等于要追加的列表数。我想要摆脱temps的主要原因是可能有8-10个函数输出,并且有许多临时变量会变得混乱(尽管我真的不喜欢有两个)。

4 个答案:

答案 0 :(得分:5)

def f():
    return 5,6

a,b = zip(*[f() for i in range(10)])
# this will create two tuples of elements 5 and 6 you can change 
# them to list by type casting it like list(a), list(b)

答案 1 :(得分:4)

第一个解决方案:我们列出所有结果,然后转置它

def f(i):
    return i, 2*i

# First make a list of all your results
l = [f(i) for i in range(5)]
# [(0, 0), (1, 2), (2, 4), (3, 6), (4, 8)]

# then transpose it using zip
a, b = zip(*l)

print(list(a))
print(list(b))
# [0, 1, 2, 3, 4]
# [0, 2, 4, 6, 8]

或者,全部在一行:

a, b = zip(*[f(i) for i in range(5)])

一个不同的解决方案,在每次迭代时构建列表,以便您可以在构建它们时使用它们:

def f(i):
    return 2*i, i**2, i**3

doubles = []
squares = []
cubes = []
results = [doubles, squares, cubes]

for i in range(1, 4):
    list(map(lambda res, val: res.append(val), results, f(i)))
    print(results)

# [[2], [1], [1]]
# [[2, 4], [1, 4], [1, 8]]
# [[2, 4, 6], [1, 4, 9], [1, 8, 27]]

print(cubes)
# [1, 8, 27]

注意list(map(...)):在Python3中,map返回一个生成器,所以如果我们想要执行lambda,我们必须使用它。list这样做。

答案 2 :(得分:3)

对于您的具体情况,zip答案很棒。

使用itertools.cycleitertools.chain是一种与现有答案不同的方法,如果你想要以循环方式添加许多预先存在的列表,这些方法可能会派上用场。当函数返回的值多于列表值时,它也可以工作。

>>> from itertools import cycle, chain
>>> a, b = [], [] # new, empty lists only for demo purposes
>>> for l, v in zip(cycle([a, b]), (chain(*(f() for i in range(10))))):
...     l.append(v)
... 
>>> a
[5, 5, 5, 5, 5, 5, 5, 5, 5, 5]
>>> b
[6, 6, 6, 6, 6, 6, 6, 6, 6, 6]

答案 3 :(得分:1)

我会做

tmp = f()
a.append(tmp[0])
b.append(tmp[1])

不确定它对你来说是多少pythonic。