问题48来自Project Euler的描述:
系列,1 ^ 1 + 2 ^ 2 + 3 ^ 3 + ... + 10 ^ 10 = 10405071317.找到最后一个 系列的十位数,1 ^ 1 + 2 ^ 2 + 3 ^ 3 + ... + 1000 ^ 1000。
我刚刚在Python中使用单行解决了这个问题:
print sum([i**i for i in range(1,1001)])%(10**10)
我几乎立即就这样做了,因为我记得在Python中分裂模型非常快。但我仍然不明白这是如何工作的(Python做了哪些优化?)以及为什么如此快。
你可以向我解释一下吗?mod 10**10
操作是否被优化为应用于列表推导的每次迭代而不是整个总和?
$ time python pe48.py
9110846700
real 0m0.070s
user 0m0.047s
sys 0m0.015s
答案 0 :(得分:4)
鉴于此
print sum([i**i for i in range(1,1001)])%(10**10)
和
print sum([i**i for i in range(1,1001)])
在Python中的功能同样快,你上一个问题的答案是'不'。
因此,Python必须能够非常快速地进行整数取幂。并且整数取幂是O(log(n))乘法:http://en.wikipedia.org/wiki/Exponentiation#Efficient_computation_of_integer_powers
基本上做的是,而不是做2 ^ 100 = 2 * 2 * 2 * 2 * 2 ... 100次,你意识到2 ^ 100也是2 ^ 64 * 2 ^ 32 * 2 ^ 4 ,你可以一遍又一遍地得到2 ^ 2然后2 ^ 4然后2 ^ 8 ......等等,一旦你找到了所有这三个组件的值,你就将它们相乘得出最终答案。这需要更少的乘法运算。如何解决它的具体细节有点复杂,但Python已经足够成熟,可以在这样的核心功能上进行优化。
答案 1 :(得分:1)
不,它适用于整个总和。总和本身计算速度非常快。如果参数是整数,那么做指数就不那么难了。