将函数输出附加到多个列表的 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.cycle
和 itertools.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]
我有一个问题,我还没有找到好的解决方案。我正在寻找一种更好的方法来将函数输出附加到两个或多个列表,而不使用临时变量。示例如下:
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.cycle
和 itertools.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]