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

Pythonic way to append output of function to several lists

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

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()) 之类的东西,但还没有完全找到解决方案。 任何删除这些临时变量的方法都会非常有用,谢谢!

编辑以获取更多信息: 在这种情况下,函数的输出数量将始终等于附加到的列表数量。我希望摆脱临时变量的主要原因是可能有 8-10 个函数输出,并且拥有那么多临时变量会变得混乱(尽管我什至不喜欢有两个)。

我愿意

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

虽然不确定它对你来说有多 pythonic。

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

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 returns一个生成器,所以如果我们想要执行lambda,我们必须使用它。list 做到了。

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)

对于您的具体情况,zip 答案非常好。

使用 itertools.cycleitertools.chain 是一种不同于现有答案的方法,如果您有很多要在一轮中附加的预先存在的列表,可能会派上用场-知更鸟时尚。当您的函数 returns 的值比您的列表多时,它也有效。

>>> 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]