减少不必要的 for 循环
注:参考于码农高天
文章目录
1. 使用comprehension、generator
from timeit import timeit
def with_for():
lst = []
for i in range(100):
lst.append(i)
return lst
def without_for():
return [i for i in range(100)]
def without_for_faster():
return (i for i in range(100))
# 使用append时python没法直接确定使用的是list的append,需要先从lst中找到append
print(f"with :{timeit(with_for, number=10000)}")
# 使用list comprehension,直接调用list.append
print(f"without:{timeit(without_for, number=10000)}")
# 使用 generator 更快
print(f"without:{timeit(without_for_faster, number=10000)}")
2. 使用builtin函数
from timeit import timeit
lst = [i for i in range(100)]
def with_for():
max_num = 0
for num in lst:
if num > max_num:
max_num = num
return max_num
def without_for():
return max(lst)
# 保存、循环、判断在C中进行会更快
print(f"with :{timeit(with_for, number=10000)}")
# 使用builtin函数会更快,例如max、min
# 运行python bytecode的时候会比在cpython中耗费时间
print(f"without:{timeit(without_for, number=10000)}")
3. 使用any、all
from timeit import timeit
lst = [i for i in range(100)]
def with_for():
for num in lst:
if num > 50:
return True
return False
def without_for():
return any(num > 50 for num in lst)
def without_for_list_comprehension():
return any([num > 50 for num in lst])
# with :0.008582599999999996
# without:0.022688
# without:0.03122409999999999
print(f"with :{timeit(with_for, number=10000)}")
# generator 运行在python层面 generator本身的建立和调用需要花费时间
print(f"without:{timeit(without_for, number=10000)}")
# 使用any、all 尽量不使用comprehension
print(f"without:{timeit(without_for_list_comprehension, number=10000)}")
from timeit import timeit
lst = [False] * 100
def with_for():
for b in lst:
if b:
return True
return False
def without_for():
return any(lst)
print(f"with :{timeit(with_for, number=10000)}")
print(f"without:{timeit(without_for, number=10000)}")
4. filter、map、zip
from timeit import timeit
lst = [i for i in range(100)]
def good(num):
return num >= 60
def with_for():
ret = []
for num in lst:
if good(num):
ret.append(num)
return ret
def without_for():
return [num for num in lst if good(num)]
def without_for_builtin():
return filter(good, lst)
print(f"with :{timeit(with_for, number=10000)}")
print(f"without:{timeit(without_for, number=10000)}")
print(f"without:{timeit(without_for_builtin, number=10000)}")
from timeit import timeit
lst = [i for i in range(100)]
def change(num):
return num * 2
def with_for():
ret = []
for num in lst:
ret.append(change(num))
return ret
def without_for():
# return (change(num) for num in lst)
return map(change, lst)
print(f"with :{timeit(with_for, number=10000)}")
print(f"without:{timeit(without_for, number=10000)}")
from timeit import timeit
lst = [i for i in range(100)]
lst2 = [i for i in range(100)]
def change(num, num2):
return num + num2
def with_for():
ret = []
for idx in range(len(lst)):
ret.append(change(lst[idx], lst2[idx]))
return ret
def without_for():
# return (change(lst[i], lst2[i])
# for i in range(len(lst)))
return map(change, lst, lst2)
print(f"with :{timeit(with_for, number=10000)}")
print(f"without:{timeit(without_for, number=10000)}")
from timeit import timeit
lst = [i for i in range(100)]
lst2 = [i for i in range(100)]
def with_for():
ret = []
for i in range(len(lst)):
ret.append((lst[i], lst2[i]))
return ret
def without_for():
return zip(lst, lst2)
print(f"with :{timeit(with_for, number=10000)}")
print(f"without:{timeit(without_for, number=10000)}")