我有一份功能列表。每个函数可以返回一个浮点数或2个浮点数列表。我需要使用列表comprhension构建一个结果的平面列表。 出于效率原因,我需要使用一次迭代来构建结果。出于同样的原因,for循环不是一个选项(这是我的信念......这是正确的吗?)。
输入:
funcs=[[function_1, arguments_function_1],[function_2,arguments_function_2]...[function_n, arguments_function_n]
其中function_j是先前定义的函数。 arguments_function_j是funtion_j的参数列表。
暂定电话:
results=[f[0](f[1]) for f in funcs]
上述调用在语法上是正确的,但不会以我需要的格式返回结果。事实上,假设第四个函数返回一个列表,最终结果将是
[1,2,3,[4,5],6] instead of [1,2,3,4,5,6] as I need
我尝试了以下内容:
results=[f[0](f[1]) if type(f[0](f[1]))==float\
else f[0](f[1])[0],f[0](f[1])[1]\
for f in funcs]
但是f[0](f[1])[0],f[0](f[1])[1]
部分在语法上并不正确。它应放在支架之间,但它不能解决问题。
任何提示? 提前致谢
答案 0 :(得分:2)
你可以使用帮助函数通过理解来创建它,但不要忘记将它与循环计时,看看你是否真的获得了性能。
import collections
def sequencify(x):
return x if isinstance(x, collections.Sequence) else (x,)
results = [x for (f, a) in funcs for x in sequencify(f(a))]
您还可以测试将sequencify
更改为特定用例是否会使其更快,例如
sequencify = lambda x: (x,) if type(f) == float else x
但是,实际上,如果您正在寻找性能,请考虑修改函数以返回带有1个浮点数而不仅仅是浮点数的元组,然后您不需要昂贵的类型检查并且可以使用标准列表展平技术:
results = [x for (f, a) in funcs for x in f(a)]
编辑 - 我的快速测试表明,返回的浮动元组比浮动列表快25%:
$ python3 -m timeit -s 'import random; funcs=[ (random.choice([lambda a: [a], lambda a: [a,a]]),random.random()) for i in range(10000) ]' 'result=[x for (f, a) in funcs for x in f(a)]'
100 loops, best of 3: 2.98 msec per loop
$ python3 -m timeit -s 'import random; funcs=[ (random.choice([lambda a: (a,), lambda a: (a,a)]),random.random()) for i in range(10000) ]' 'result=[x for (f, a) in funcs for x in f(a)]'
100 loops, best of 3: 2.27 msec per loop
答案 1 :(得分:1)
你只需要链接你的值而不是
results=[f[0](f[1]) for f in funcs]
只是做
import itertools
result = list(itertools.chain.from_iterable(f[0](f[1]) for f in funcs))
(这会压缩你的结果列表,包含在list
中以强制迭代)