Python中的迭代函数
给定一个函数Python中的迭代函数,python,Python,给定一个函数f()、一个数字x和一个整数N,我要计算列表: y = [x, f(x), f(f(x)), ..., f(f... M times...f(f(x)) ] 在Python中执行此操作的一个明显方法是以下Python代码: y = [x] for i in range(N-1): y.append(f(y[-1])) 但我想知道是否有更好或更快的方法来实现这一点。您可以使用发电机: import itertools def apply_apply(f, x_0):
f()
、一个数字x
和一个整数N
,我要计算列表:
y = [x, f(x), f(f(x)), ..., f(f... M times...f(f(x)) ]
在Python中执行此操作的一个明显方法是以下Python代码:
y = [x]
for i in range(N-1):
y.append(f(y[-1]))
但我想知道是否有更好或更快的方法来实现这一点。您可以使用发电机:
import itertools
def apply_apply(f, x_0):
x = x_0
while True:
yield x
x = f(x)
....
y = list(itertools.islice(apply_apply(f, x), N))
另一种方法是走全功能路线:
from functools import reduce
y = list(reduce(lambda x, f: x + [f(x[-1])], [[x_0]] + [f] * (N - 1)))
作为旁注,这两种解决方案在我的机器上的性能都比公认的解决方案好,发电机为2ms,功能为2ms,雷蒙德代码为4ms,代码为f=lambda x:x*x
,x_0=2
和N=20
对于
lambda x:2*x
Raymond的版本,其速度略快于生成器方法,且远快于功能变体。这似乎取决于f
的复杂性,尽管我不知道如何…有几种方法可以优化此代码:
itertools.repeat(None,times)
可以更快地控制循环的数量(这可以避免在每次迭代中创建新的、未使用的整数对象)[-1]
索引查找(LOAD\u FAST/STORE\u FAST比LOAD\u CONST-1和BINARY\u SUBSCR更快)y.append
来提高速度from itertools import repeat
def nest(func, x, times):
result = [x]
result_append = result.append
for _ in repeat(None, times):
x = func(x)
result_append(x)
return result
下面是一个示例调用:
>>> def double(x):
return 2 * x
>>> nest(double, 3, 5)
[3, 6, 12, 24, 48, 96]
以下是显示紧密内环、局部变量使用和绑定方法的反汇编:
>>> from dis import dis
>>> dis(nest)
2 0 LOAD_FAST 1 (x)
3 BUILD_LIST 1
6 STORE_FAST 3 (result)
3 9 LOAD_FAST 3 (result)
12 LOAD_ATTR 0 (append)
15 STORE_FAST 4 (result_append)
4 18 SETUP_LOOP 45 (to 66)
21 LOAD_GLOBAL 1 (repeat)
24 LOAD_CONST 0 (None)
27 LOAD_FAST 2 (times)
30 CALL_FUNCTION 2
33 GET_ITER
>> 34 FOR_ITER 28 (to 65)
37 STORE_FAST 5 (_)
5 40 LOAD_FAST 0 (func)
43 LOAD_FAST 1 (x)
46 CALL_FUNCTION 1
49 STORE_FAST 1 (x)
6 52 LOAD_FAST 4 (result_append)
55 LOAD_FAST 1 (x)
58 CALL_FUNCTION 1
61 POP_TOP
62 JUMP_ABSOLUTE 34
>> 65 POP_BLOCK
7 >> 66 LOAD_FAST 3 (result)
69 RETURN_VALUE
for循环中的行应该是“y.append(f(y[-1])”@Ryaan G:是的,应该是,谢谢。f是什么?也许不需要重复应用函数就可以解决它。简单的例子:def(n):返回n+1有趣的问题:)注意,在Python>=3.3中,有一种基于时间的方法,很难为列表构建代码获得有意义的时间度量。随着列表的增长,会定期调用realloc()。根据碎片的不同,该调用要么是即时的(可用空间溢出),要么是缓慢的(必须复制所有数据)。我本来会发布一个生成器解决方案(没有这些问题),但OP特别要求提供一个列表,并询问如何优化其解决问题的方法。