繁体   English   中英

列表理解和for循环之间的性能差异

[英]Performance difference between list comprehensions and for loops

我有一个脚本,可以查找所有数字的总和,这些数字可以写为其数字的五次幂。 (此问题在Project Euler网站上有更详细的描述。)

我用两种方法编写它,但是我不了解性能差异。

第一种方法使用嵌套列表推导:

exp = 5

def min_combo(n):
    return ''.join(sorted(list(str(n))))

def fifth_power(n, exp):
    return sum([int(x) ** exp for x in list(n)])

print sum( [fifth_power(j,exp) for j in set([min_combo(i) for i in range(101,1000000) ]) if int(j) > 10 and j == min_combo(fifth_power(j,exp)) ] )

和如下配置文件:

$ python -m cProfile euler30.py
443839   
         3039223 function calls in 2.040 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
  1007801    1.086    0.000    1.721    0.000 euler30.py:10(min_combo)
     7908    0.024    0.000    0.026    0.000 euler30.py:14(fifth_power)
        1    0.279    0.279    2.040    2.040 euler30.py:6(<module>)
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
  1007801    0.175    0.000    0.175    0.000 {method 'join' of 'str' objects}
        1    0.013    0.013    0.013    0.013 {range}
  1007801    0.461    0.000    0.461    0.000 {sorted}
     7909    0.002    0.000    0.002    0.000 {sum}

第二种方法是for循环更常用for

exp = 5
ans= 0

def min_combo(n):
    return ''.join(sorted(list(str(n))))


def fifth_power(n, exp):
    return sum([int(x) ** exp for x in list(n)])


for j in  set([ ''.join(sorted(list(str(i)))) for i in range(100, 1000000) ]):
    if int(j) > 10:

        if j ==  min_combo(fifth_power(j,exp)):
            ans += fifth_power(j,exp)

print 'answer', ans

这再次是概要分析信息:

$ python -m cProfile euler30.py 
answer 443839
         2039325 function calls in 1.709 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     7908    0.024    0.000    0.026    0.000 euler30.py:13(fifth_power)
        1    1.081    1.081    1.709    1.709 euler30.py:6(<module>)
     7902    0.009    0.000    0.015    0.000 euler30.py:9(min_combo)
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
  1007802    0.147    0.000    0.147    0.000 {method 'join' of 'str' objects}
        1    0.013    0.013    0.013    0.013 {range}
  1007802    0.433    0.000    0.433    0.000 {sorted}
     7908    0.002    0.000    0.002    0.000 {sum}

为什么列表理解实现比for循环实现多调用min_combo()1,000,000次?

因为在第二个代码中,您再次在set调用中实现了min_combo的内容...

做同样的事情,您将得到相同的结果。

顺便说一句,更改这些以避免创建大列表:

sum([something for foo in bar]) -> sum(something for foo in bar)

set([something for foo in bar]) -> set(something for foo in bar)

(不[...]他们成为发电机表达式)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM