我是靠谱客的博主 冷傲缘分,最近开发中收集的这篇文章主要介绍python一些操作的效率对比,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

内容包括

用途推荐方式
生成list一维使用[0]*n,二维采用[0]*n嵌套for-range的形式
list与set频繁的删除元素,如果不需要根据索引查看内容的话,使用set更节约时间

list生成效率

有时做leetcode题目时,存储结果需要提前生成固定大小的list,那么方式更快一些呢?以生成二维list为例

首先是[0]*n+for—range的方式

import time
start = time.time()
for i in range(1000):
    temp = [[0]*1000 for _ in range(1000)]
end = time.time()
print(end - start)#5.878307104110718s

首先是for—range+for—range的方式

import time
start = time.time()
for i in range(1000):
    temp = [[0 for _ in range(1000)] for _ in range(1000)]
end = time.time()
print(end - start)#30.824012517929077s

结论[0]*n+for—range更快,有人会想到使用[[0]*n]*n生成二维list,这样速度是最快的,但是实际上会出现如下问题,这五个子list其实都是同一个list,对其中一个更改会导致均发生更改,无法完成自己想要的操作。


>>> a = [[0]*5]*5
>>> a
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
>>> a[0][0] = 5
>>> a
[[5, 0, 0, 0, 0], [5, 0, 0, 0, 0], [5, 0, 0, 0, 0], [5, 0, 0, 0, 0], [5, 0, 0, 0, 0]]

list与set效率对比

首先list的底层实现是一个类数组结构,具体文章可以看这里

http://www.laurentluce.com/posts/python-list-implementation/

而set底层是一种hash表的结构,这就导致二者增删操作的差异性,set优于list,但是无法进行对于下标的索引
list增加操作

import time
temp = []
start = time.time()
for i in range(int(1e8)):
    temp.append(i)
end = time.time()
print(end - start)#8.463991403579712s

set的增加操作

import time
temp = set()
start = time.time()
for i in range(int(1e8)):
    temp.add(i)
end = time.time()
print(end - start)#10.350674152374268s

关于增加的操作,二者没有过大的差别,这是归功于list的提前扩大内容量的原理,见上面的链接
list的删除操作

import time
temp = [i for i in range(int(1e5))]
start = time.time()
for i in range(int(1e5)):
    temp.remove(i)
end = time.time()
print(end - start)#0.9296932220458984s

set的删除操作

import time
temp = set([i for i in range(int(1e5))])
start = time.time()
for i in range(int(1e5)):
    temp.remove(i)
end = time.time()
print(end - start)#0.010970592498779297s

可以看到是数量级的差异,这时因为remove在list操作中是O(n)复杂度的操作,而在set中是O(1)的复杂度

可能的疑惑

在使用for循环的时候,对于temp这种可迭代的对象有一个疑问for i in range(len(temp)):这种使用方式与提前计算出n=len(temp),而后使用for i in range(n)会不会更加优化,毕竟看起来前者每次循环都会计算一个len(temp)后判断是否应该继续循环(来源于c的想法)
下面进行测试
第一种方式

import time
temp = ["a"]*int(1e7)
start = time.time()
for i in range(len(temp)):
    pass
end = time.time()
print(end - start)#0.30315184593200684s

第二种看似节约时间的方式

import time
temp = ["a"]*int(1e7)
n = len(temp)
start = time.time()
for i in range(n):
    pass
end = time.time()
print(end - start)#0.3273622989654541s

忽略了计算机每次的误差,可以认为两种方式的耗时是相同的,可以认为在第一种方式中,仅仅在第一次循环中计算了len(temp)的值,而后便判断是否满足条件便可以了,当然在循环中改变迭代对象的大小一定会重新调用len(temp)的函数的

但当使用while的时候
第一种方式

import time
temp = ["a"]*int(1e8)
start = time.time()
i = 0
while i < len(temp):
    i += 1
end = time.time()
print(end - start)#12.039517164230347s

第二种方式

import time
temp = ["a"]*int(1e8)
n = len(temp)
start = time.time()
i = 0
while i < n:
    i += 1
end = time.time()
print(end - start)#7.073049068450928s

可以看出while循环每次判断都使用了len(temp)函数,说明使用for循环的时候对range(len(temp))进行了优化

最后

以上就是冷傲缘分为你收集整理的python一些操作的效率对比的全部内容,希望文章能够帮你解决python一些操作的效率对比所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(57)

评论列表共有 0 条评论

立即
投稿
返回
顶部