1.ipython
ipython(交互环境)中的timeit可以查看tuple ,list的创建时间(性能)
🌟安装ipython :pip install ipython
🌟在teiminal中输入ipython进入
测试创建元祖,列表的速度:

为什么列表的创建时间长?
列表存储快满的时候,底层会自动给列表扩容。-----列表的内存大小是变化的
但是元祖创建的时候,定义的时候是多大,python解释器分配内存的时候,就安装定义时的大小分配-----元祖的内存大小是固定的,占用的内存要小很多
元祖的性能高于列表。
但是,在现实中使用,列表使用的频率高。---灵活
数据是固定不变的,用元祖,性能好。
上面的timeit模块,是可以测试模块性能的。
timeit模块中的Timer类,测试字符串、列表、函数的运行速度
看下Timer类的源码:stmt参数传入的是带测试时间的参数(列表,元祖要放在字符串中,函数不需要),setup是计时规则,一般不用,number是测试次数,默认值1000万次
def __init__(self, stmt="pass", setup="pass", timer=default_timer, globals=None): """Constructor. See class doc string.""" self.timer = timer local_ns = {} global_ns = _globals() if globals is None else globals init = ''
下面用timeit的Timer类进行测试:
import timeit def func(): for idx in range(10): print(idx) resp1 = timeit.Timer(func).timeit(10) resp2 = timeit.Timer("[1,2,3]").timeit(10) resp3 = timeit.Timer("(1,2,3)").timeit(10) print(resp1) print(resp2) print(resp3)
结果:返回的时间是科学计数法,元祖的运行时间比列表的时间短

可以用上面的方法,为自己写的功能函数测试速度。
也可以直接使用timeit.timeit()来测试运行时间。
# resp4 = timeit.timeit(func) resp5 = timeit.timeit("[1,2,3]") resp6 = timeit.timeit("(1,2,3)") # print(resp4) print(resp5) print(resp6)
timeit模块中的timeit()函数,实际上是对Timer类的封装,使用起来更加方便。(对比上面Timer类),timeit()函数的返回值Timer().timeit(),就是利用TImer类测时间的表达
def timeit(stmt="pass", setup="pass", timer=default_timer, number=default_number, globals=None): """Convenience function to create Timer object and call timeit method.""" return Timer(stmt, setup, timer, globals).timeit(number)
timeit()源码中的参数number是运行多少次的意思
举个例子:
from timeit import timeit def get_num(): for idx in range(10): print(idx) resp1 = timeit(get_num,number=2) print(resp1)
2.命名元祖----使用起来更像对象
Python元组的升级版本 -- namedtuple(具名元组)
因为元组的局限性:不能为元组内部的数据进行命名,所以往往我们并不知道一个元组所要表达的意义,所以在这里引入了 collections.namedtuple 这个工厂函数,来构造一个带字段名的元组。具名元组的实例和普通元组消耗的内存一样多,因为字段名都被存在对应的类里面。这个类跟普通的对象实例比起来也要小一些,因为 Python 不会用 __dict__ 来存放这些实例的属性。
namedtuple 对象的定义如以下格式:
collections.namedtuple(typename, field_names, verbose=False, rename=False)
返回一个命名元组子类 typename,其中参数的意义如下:
- typename:元组名称
- field_names: 元组中元素的名称,用列表、字符串都可以表示
- rename: 如果元素名称中含有 python 的关键字,则必须设置为 rename=True
- verbose: 默认就好
举个例子
1⃣️元祖中的元素名,存储在list中,
####命名元祖 import collections User = collections.namedtuple("User",["name","age","gender"]) #返回User对象 user = User("zhangsan",17,"boy") print(user) #output:User(name='zhangsan', age=17, gender='boy')
2⃣️元祖中的元素名,放在字符串里,入参,字符串中元素用逗号隔开
####命名元祖 import collections User = collections.namedtuple("User","name,age,gender") user = User("zhangsan",17,"boy") print(user) #output:User(name='zhangsan', age=17, gender='boy') #查找元素 print(user.name) print(user.age) print(user.gender) print(User) #output: # zhangsan #17 #boy #<class '__main__.User'>
上面的字符串形式的,看下源码,将字符串转化为list
if isinstance(field_names, str): field_names = field_names.replace(',', ' ').split() field_names = list(map(str, field_names)) typename = _sys.intern(str(typename))
注意:
1⃣️一般,typename元祖名字与返回的对象是用一样的,不是重点。
输出结果可以看出,元组的名字就是定义时的User,元素有对应的元素名。
2⃣️设定命名元组的元素名有多少个,你创建的元组中元素个数就有多少个,个数要跟设定时元素名的个数一样-------------个数,顺序,要一一对齐。
["name","age","gender"] 与 ("zhangsan",17,"boy")
那么,元素有对应的元素名,怎么查找呢???-----注意,和字典的查找进行区分。
命名元素的查找格式:.属性 的方式
####命名元祖 import collections User = collections.namedtuple("User",["name","age","gender"]) user = User("zhangsan",17,"boy") print(user) #output:User(name='zhangsan', age=17, gender='boy') #查找元素 print(user.name) print(user.age) print(user.gender) print(User) #output: #zhangsan #17 #boy #<class '__main__.User'>
查看user的类型,上面的print(user),得到的是一个User的类,就是typename
浙公网安备 33010602011771号