python教程—为什么for循环计算真值要快得多?-Python实用宝典

python教程—为什么for循环计算真值要快得多?

```def count_even_digits_spyr03_for(n):
count = 0
for c in str(n):
if c in "02468":
count += 1
return count

def count_even_digits_spyr03_sum(n):
return sum(c in "02468" for c in str(n))```

```def count_even_digits_spyr03_list(n):
return [c in "02468" for c in str(n)].count(True)```

```def count_even_digits_spyr03_sum2(n):
return sum(1 for c in str(n) if c in "02468")```

答案

sum速度很快，但是sum并不是导致速度放缓的原因。放缓的主要原因有三个:

• 使用生成器表达式会产生不断暂停和恢复生成器的开销。
• 您的生成器版本无条件地添加，而不是仅当数字为偶数时才添加。当数字是奇数时，这将非常消耗资源。
• 添加布尔值而不是int值可以防止sum使用其整数快速路径。

```In [66]: def f1(x):
....:     return sum(c in '02468' for c in str(x))
....:
In [67]: def f2(x):
....:     return sum([c in '02468' for c in str(x)])
....:
In [68]: x = int('1234567890'*50)
In [69]: %timeit f1(x)
10000 loops, best of 5: 52.2 µs per loop
In [70]: %timeit f2(x)
10000 loops, best of 5: 40.5 µs per loop```

```def count_even_digits_spyr03_for(n):
count = 0
for c in str(n):
if c in "02468":
count += 1
return count```

```In [71]: def f3(x):
....:     return sum([True for c in str(x) if c in '02468'])
....:
In [72]: %timeit f3(x)
10000 loops, best of 5: 34.9 µs per loop```

f1,相同的原始代码，花费了52.2µs，f2只有列表理解解析式,花了40.5µs，f3增加了if，只花了34.9µs，而且还能更快哦。

`if (PyLong_CheckExact(item)) {`

```In [73]: def f4(x):
....:     return sum([1 for c in str(x) if c in '02468'])
....:
In [74]: %timeit f4(x)
10000 loops, best of 5: 33.3 µs per loop```

```In [75]: def explicit_loop(x):
....:     count = 0
....:     for c in str(x):
....:         if c in '02468':
....:             count += 1
....:     return count
....:
In [76]: %timeit explicit_loop(x)
10000 loops, best of 5: 32.7 µs per loop```

```def f5(x):
return len([1 for c in str(x) if c in '02468'])```

```def f6(x):
s = str(x)
return sum(s.count(c) for c in '02468')```

```>>> import timeit
>>> def f(x):
...     return sum([1 for c in str(x) if c in '02468'])
...
>>> def g(x):
...     return len([1 for c in str(x) if c in '02468'])
...
>>> def h(x):
...     s = str(x)
...     return sum(s.count(c) for c in '02468')
...
>>> x = int('1234567890'*50)
>>> timeit.timeit(lambda: f(x), number=10000)
0.331528635986615
>>> timeit.timeit(lambda: g(x), number=10000)
0.30292080697836354
>>> timeit.timeit(lambda: h(x), number=10000)
0.15950968803372234
>>> def explicit_loop(x):
...     count = 0
...     for c in str(x):
...         if c in '02468':
...             count += 1
...     return count
...
>>> timeit.timeit(lambda: explicit_loop(x), number=10000)
0.3305045129964128```

​Python实用宝典 (pythondict.com)