1. 列表表达式和生成器
要从一个可迭代对象中取数据建立一个 list
from timeit import timeit
def with_for():
lst = []
for i in range(1000):
lst.append(i)
return lst
def without_for():
return [i for i in range(1000)]
print(f"with: {timeit(with_for, number=10000)}")
print(f"without:{timeit(without_for, number=10000)}")
运行结果
with: 0.303983400001016
without:0.16779089999909047
可以看到列表表达式要 For 循环快将近一倍
最大的影响因素就是这个 append
函数,在做 lst.append()
时,python 没有办法直接判断你使用的就是列表的 append
的函数。所以想要从 lst
中找到 append
这个函数再拿出来,再调用它。而当使用列表表达式的时候,python 就可以直接去调用那个列表的 append
函数了。
将 []
改成 ()
就得到了生成器,由于没有建立这个列表,而是建立了一个生成器,这个操作比列表表达式还要快非常多。
from timeit import timeit
def with_for():
lst = []
for i in range(1000):
lst.append(i)
return lst
def without_for():
return (i for i in range(1000))
print(f"with: {timeit(with_for, number=10000)}")
print(f"without:{timeit(without_for, number=10000)}")
结果
with: 0.3137756999967678
without:0.0028984999989916105
2. max() 和 min()
这两个函数分别是求可迭代对象中的最大值和最小值
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)
print(f"with: {timeit(with_for, number=10000)}")
print(f"without:{timeit(without_for, number=10000)}")
结果
with: 0.021164999998291023
without:0.0069537999988824595
能用 bulletin
完成的代码,不要用 python 写
3. any() 和 all()
3.1 any()
找遍一个列表,如果发现一个什么样的东西直接返回 True
,否则的话返回 False
比如查找列表中有没有大于 50 的数
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)
print(f"with: {timeit(with_for, number=10000)}")
print(f"without:{timeit(without_for, number=10000)}")
结果
with: 0.009332400000857888
without:0.019502699997246964
运行后发现使用 any()
会比直接写 python 还要慢一些,这里的原因是生成器的本身还是运行在 python 层面的,而生成器的建立调用本身是有代价的,所以使用 any()
的时候反而更慢了 。事实上如果我们没有这个生成器,而是直接在一个列表里找 True
的话,any()
要比 python 的写法更快的。
3.2 all()
当要判断一个可迭代对象里面是不是全都是 True
的时候,可以使用 all()
from timeit import timeit
lst = [i for i in range(100)]
def with_for():
for num in lst:
if num > 100:
return False
return True
def without_for():
return all(num <= 100 for num in lst)
print(f"with: {timeit(with_for, number=10000)}")
print(f"without:{timeit(without_for, number=10000)}")
结果
with: 0.015045099997223588
without:0.033781900001486065
当我们在使用 any()
或者 all()
的时候,要使用生成器而不用列表表达式
4. filter()
用第一个函数来判断这个值要不要
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 [filter(good, lst)]
print(f"with: {timeit(with_for, number=10000)}")
print(f"without:{timeit(without_for, number=10000)}")
结果
with: 0.059730799999670126
without:0.0014754000003449619
5. map()
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)}")
结果
with: 0.0747945000002801
without:0.0008847999997669831
map()
可以接收多个参数
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[idx], lst2[idx]) 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)}")
结果
with: 0.09803069999907166
without:0.0011946000013267621
6. zip()
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], lst[1]))
return ret # [(0, 0), (1, 1), (2, 2)...]
def without_for():
return zip(lst, lst2)
print(f"with: {timeit(with_for, number=10000)}")
print(f"without:{timeit(without_for, number=10000)}")
结果
with: 0.0706549000024097
without:0.0015113999979803339
例子
from timeit import timeit
names = ["Alice", "Bob", "Charlie"]
ages = [18, 16, 19]
scores = [3, 4, 5]
def with_for():
for i in range(len(names)):
name = names[i]
age = age[i]
score = scores[i]
print(name, age, score)
def without_for():
for name, age, score in zip(names, ages, scores):
print(name, age, score)
print(f"with: {timeit(with_for, number=1)}")
print(f"without:{timeit(without_for, number=1)}")
结果
Alice 18 3
Bob 16 4
Charlie 19 5
with: 0.00031540000054519624
Alice 18 3
Bob 16 4
Charlie 19 5
without:0.0002550999997765757