2017-04-19 50 views
1

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

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) 

我试着玩东西像拉链(* f()),但还没有找到一个解决方案。 任何方式来删除那些临时变量将是非常有用的,谢谢!

编辑其他信息: 在这种情况下,函数的输出数将始终等于要追加的列表数。我期望摆脱临时工的主要原因是可能有8-10个函数输出,并且有许多临时变量会变得杂乱无章(尽管我并不喜欢有两个)。

+0

您是否需要在for循环的每次迭代中调用函数,或者只需调用一次? – iafisher

+0

列表的数量是否总是等于函数返回的元组中元素的数量,或者,如果函数只返回一个单一的东西,是否需要将该项目追加到所有列表中?你的问题有点含糊。 – martineau

+1

如果您想编写“Pythonic”代码,我建议您阅读并遵循[PEP 8 - Python代码风格指南](https://www.python.org/dev/peps/pep-0008/),在许多其他事情中,建议用4个空格缩进。 – martineau

回答

4
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

我做

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

不知道这是给你的,虽然如何Python的。

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] 

关于的注意事项3210:在Python3中,map返回一个生成器,所以如果我们想要执行lambda,我们必须使用它。 list做到了。

+0

有人可能会说这使用了一个临时变量,即'l'。并且在构建时很难使用这些列表。 – ilkkachu

+0

这应该适用于我的大部分用例,谢谢。 – halolord01

+0

@ilkkachu:我添加了一个解决您的第二点的不同解决方案。 –

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]