数据类型之元组和列表的性能分析、命名元组

存储 存储软件
元组和列表用来存储数据,在元组和列表里面查询的时候,到底哪个更快呢?计算创建元组和列表所需的时间:ipython 中使用timeit这个命令。

[[375462]]

 目录

  • 一、元组和列表
    • 1.元组和列表的性能分析
    • 2.为什么列表在 Python 中是最常用的呢?
    • 3.timeit 里面有个 Timer 类
    • 4.timeit 里面还有个直接用的 timeit 的方法,timeit.timeit()
    • 5.这 2 个方法有啥区别?
  • 二、命名元组
  • 三、命名元组有什么特点?

一、元组和列表

元组vs列表

 

1.元组和列表的性能分析

元组和列表用来存储数据,在元组和列表里面查询的时候,到底哪个更快呢?

计算创建元组和列表所需的时间:ipython 中使用timeit这个命令。

计算时间模块介绍:

  1. import timeit 
  2. #timeit.timeit 

可以用这个模块来测试函数的性能。

安装 ipython:pip install ipython

 

ipython 是个交互环境,就跟我们输入 Python 进去是一样的。只不过它外面做了一层封装,比 Python 交互环境更好用一点。

ipython 里面有一个命令叫做timeit,后面可以跟一个 Python 表达式。

例如定义一个列表在后面:

 

敲完这行命令,返回了一行时间。这个是在内存中初始化一个列表,如图可以看到创建了一千万次,时间是 48.4ns

可以看出,创建一个元组比创建一个列表要快得多。

元组的速度比列表要快 3 倍多。在内存里,当我们创建一个列表的时候,会划分一块区域出来,拿一块区域给列表来储存值。例如初始化,里面给它留了 20 个位置在这个列表里面储存值。

列表占用内存如图

 

当储存到一定程度,Python 解释器检测到列表快要盛满了的时候,它会对列表做一个扩容。

给扩容到 200,当存储到 150 的时候,发现又快存储满了,又会给你继续扩容。

随着数据的增多,底层会不断给这个列表扩容。

初始化一个元组,同样也是一千万次,只需 12.8ns

 

元组是一个不可变的类型。

比如定义的元组里面有 3 个元素,Python 解释器在给它分内存的时候,就给它分了 3 个格子。

这里面只能存 3 条数据,就这么大,所以元组占用的内存比列表要少。

元组和列表内存占用对比图

 

用一个列表存储 50 条数据和用一个元组存储 50 条数据,那么元组占用的内存要比列表小得多。

2.为什么列表在 Python 中是最常用的呢?

因为列表比较灵活,用列表的话,可以往里面不断得添加元素。如果元素固定的,那就用元组。

3.timeit 里面有个 Timer 类。

来看看这个类的源码:


 

 

timer=default_timer代表的是:创建一个列表、元组等,它要执行的一个次数。

看源码,默认是一千万次:

 

import timeit # 这个模块可以用来做性能分析def func(): for i in range(10): print(i)# 这个对象有个方法叫做timeitres = timeit.Timer(func).timeit(100) # 把这个func函数传进去,运行100次,然后返回的是个时间# timeit.Timer(func).timeit(100)中函数func是不需要加引号的,如果是字符串、列表这些需要加# 引号放进去print(res)

可以看到运行 100 次需要的时间是:0.0043269999999999975

4.timeit 里面还有个直接用的 timeit 的方法,timeit.timeit()

  1. import timeit  # 这个模块可以用来做性能分析 
  2.  
  3.  
  4. def func(): 
  5.     for i in range(10): 
  6.         print(i) 
  7.  
  8. # 这个对象有个方法叫做timeit 
  9. # res = timeit.Timer(func).timeit(100) # 把这个func函数传进去,运行100次,然后返回的是个时间 
  10. # timeit.Timer(func).timeit(100)中函数func是不需要加引号的,如果是字符串、列表这些需要加引号放进去 
  11.  
  12. # print(res) 
  13.  
  14. res2 = timeit.timeit('[1,2,3]'
  15. print(res2) 

这个模块的作用: 大家写的功能函数,可以用它测下功能函数的速度,执行大概要多久。

默认是一千万次,结果如下:

 

如果列表不加引号直接传是会报错的:

 

提示不可被调用!

5.这 2 个方法有啥区别?

其实它们是一个东西。

 

二、命名元组

元组的性能是大大优于列表的。元组、列表在使用的时候,都是通过下标索引取值的。

下标索引取值不太人性化,如果我知道数据储存在元组里面,但是我不知道它具体储存的下标位置。这个时候找这个元素,还得先把下标找出来,知道下标再去拿,这样很不方便。

字典的话,这方面就比较有优势。数据是存储在字典里面的,只要通过键,就能把值找到。字典相对于元组和列表,有一定的优势和劣势。

命名元组使用的时候可以让元组像字典一样去取值。

例如,有个元组里面保存了 3 条数据:

创建一个命名元组的话,需要用到 Python 的一个内置模块from collections import namedtuple

  1. import timeit  # 这个模块可以用来做性能分析 
  2. from collections import namedtuple 
  3. # namedtuple是个函数,创建命名元组可以通过这个函数来创建 
  4.  
  5. def func(): 
  6.     for i in range(10): 
  7.         print(i) 
  8.  
  9. # 这个对象有个方法叫做timeit 
  10. # res = timeit.Timer(func).timeit(100) # 把这个func函数传进去,运行100次,然后返回的是个时间 
  11. # timeit.Timer(func).timeit(100)中函数func是不需要加引号的,如果是字符串、列表这些需要加引号放进去 
  12.  
  13. # print(res) 
  14.  
  15. res2 = timeit.timeit('[1,2,3]'
  16.  
  17. print(res2) 
  18.  
  19.  
  20. # 命名元组 
  21.  
  22. # 如果知道里面储存的具体位置,可以通过下标取值。例如tu=[0] 
  23. # 如果我不知道名字存储在哪里,通过下标去取值就不好取了 
  24.  
  25. # 命名元组可以使取值的时候像列表一样取 
  26.  
  27. student_info = namedtuple('info_tuple',['name','age','gender']) # 这个函数接收2个参数,第一个参数是创建命名元组的类型的名字; 
  28. # 第二个参数的话,传一个列表 
  29. # 列表里写创建命名元组的一个命名,例如第一个元素命名为name 
  30. # 这个函数调用传了2个参数,返回出来一个对象。这个对象叫做student_info 
  31. # 通过这个对象student_info创建命名元组 
  32.  
  33. tu = student_info('qinghan',18,'nv'
  34. print(tu) 

 

这个 tu 就是个命名元组。

student_info 是通过命名元组这个namedtuple函数创建命名元组类型:namedtuple('info_tuple',['name','age','gender'])。

然后返回出来一个对象student_info

通过student_info这个对象传入对应的元组,定义元组的时候就通过这个对象把元素写进去,返回的就是命名元组。

三、命名元组有什么特点?

它取值的时候可以像字典一样取值,通过对应的键,找到对应的值。命名元组使用起来更像对象。

这样用:命名元组.name

这样就能找到 name 所对应的值:

  1. import timeit  # 这个模块可以用来做性能分析 
  2. from collections import namedtuple 
  3. # namedtuple是个函数,创建命名元组可以通过这个函数来创建 
  4.  
  5. def func(): 
  6.     for i in range(10): 
  7.         print(i) 
  8.  
  9. # 这个对象有个方法叫做timeit 
  10. # res = timeit.Timer(func).timeit(100) # 把这个func函数传进去,运行100次,然后返回的是个时间 
  11. # timeit.Timer(func).timeit(100)中函数func是不需要加引号的,如果是字符串、列表这些需要加引号放进去 
  12.  
  13. # print(res) 
  14.  
  15. res2 = timeit.timeit('[1,2,3]'
  16.  
  17. print(res2) 
  18.  
  19.  
  20. # 命名元组 
  21.  
  22. # 如果知道里面储存的具体位置,可以通过下标取值。例如tu=[0] 
  23. # 如果我不知道名字存储在哪里,通过下标去取值就不好取了 
  24.  
  25. # 命名元组可以使取值的时候像列表一样取 
  26.  
  27. student_info = namedtuple('info_tuple',['name','age','gender']) # 这个函数接收2个参数,第一个参数是创建命名元组的类型的名字; 
  28. # 第二个参数的话,传一个列表 
  29. # 列表里写创建命名元组的一个命名,例如第一个元素命名为name 
  30. # 这个函数调用传了2个参数,返回出来一个对象。这个对象叫做student_info 
  31. # 通过这个对象student_info创建命名元组 
  32.  
  33. tu = student_info('qinghan',18,'nv'
  34. print(tu.name

 

设定命名元组类型的时候,它返回的这个对象它里面只包含了传进去的这几个名字。

接下来,要创建命名元组的时候,元素和它一样多,名字和对应的元素的值是一一对应的,不能多,不能少。

否则就会报错:

 

print(type(tu)) # 看下它的类型

 

它返回的对象和类型名用的同一个名字。

print(type(student_info))

  1. import timeit  # 这个模块可以用来做性能分析 
  2. from collections import namedtuple 
  3. # namedtuple是个函数,创建命名元组可以通过这个函数来创建 
  4.  
  5. def func(): 
  6.     for i in range(10): 
  7.         print(i) 
  8.  
  9. # 这个对象有个方法叫做timeit 
  10. # res = timeit.Timer(func).timeit(100) # 把这个func函数传进去,运行100次,然后返回的是个时间 
  11. # timeit.Timer(func).timeit(100)中函数func是不需要加引号的,如果是字符串、列表这些需要加引号放进去 
  12.  
  13. # print(res) 
  14.  
  15. res2 = timeit.timeit('[1,2,3]'
  16.  
  17. print(res2) 
  18.  
  19.  
  20. # 命名元组 
  21.  
  22. # 如果知道里面储存的具体位置,可以通过下标取值。例如tu=[0] 
  23. # 如果我不知道名字存储在哪里,通过下标去取值就不好取了 
  24.  
  25. # 命名元组可以使取值的时候像列表一样取 
  26. # 设定命名元组类型 
  27. # student_info是个类 
  28. student_info = namedtuple('student_info',['name','age','gender']) # 这个函数接收2个参数,第一个参数是创建命名元组的类型的名字; 
  29. # 第二个参数的话,传一个列表 
  30. # 列表里写创建命名元组的一个命名,例如第一个元素命名为name 
  31. # 这个函数调用传了2个参数,返回出来一个对象。这个对象叫做student_info 
  32. # 通过这个对象student_info创建命名元组 
  33.  
  34. tu = student_info('qinghan',18,'nv'
  35. print(tu.name
  36.  
  37. print(type(tu)) # 看下它的类型 
  38. print(type(student_info)) 
  39. # 因为student_info是个类,所以看student_info的type就是个type。随便看哪个类都是一样的。 

本文转载自微信公众号「清菡软件测试」,可以通过以下二维码关注。转载本文请联系清菡软件测试公众号。

 

责任编辑:武晓燕 来源: 清菡软件测试
相关推荐

2022-03-03 17:06:24

序列类型新增元素Python

2023-05-05 08:53:38

迭代器生成器Python

2009-12-04 09:14:05

.NET 4.0

2023-11-02 13:33:00

Python数据结构

2009-06-17 13:57:25

Scala元组数组

2022-10-30 14:22:25

Python编程模块

2023-06-30 17:56:31

Scala元组

2023-10-20 08:18:17

Python数据类型

2021-04-01 15:02:56

Python循环编程

2010-03-11 15:56:15

Python列表

2022-05-19 09:01:08

TypeScript元组对象

2023-10-19 07:42:37

Python数据类型

2016-08-18 14:13:55

JavaScript基本数据引用数据

2018-11-15 09:45:47

JavaScript数据类型变量

2023-07-12 08:29:58

TypeScrip元组元素

2010-07-22 17:57:40

2020-10-20 14:50:26

Python数字字符串

2023-05-23 18:11:12

Rust数组元组

2010-10-15 13:28:34

MySql数据类型

2011-05-26 13:54:04

Json
点赞
收藏

51CTO技术栈公众号