前言

列表(list)和 元组(tupple) 是 Python 中常见的两种数据结构.这两者使用方法有一定的相似,俩者都是 Python 内置类型,都可以保存数据集合,都可以保存复合数据,我们同样可以通过索引去访问它们.

那么问题来了,俩者究竟有区别吗???

list 和 tupple 的区别

首先回答问题.list 和 tupple 有区别吗?答案是肯定的,两者有区别. list 和 tupple 的本质区别在于,前者是一个可变对象而后者是一个不可变对象。

什么是可变对象和不可变对象呢?简单地来说,可变对象就是创建之后可以修改,而不可变对象则是创建之后不允许在修改。

没关系,让我们看一下例子

首先创建一个 list

>>> a = ["a","b","c","d"]

接着我们试着修改一下上面的 list , 将 b 改成 e,看看会发生什么

>>> a[1] = "e"
>>> a
['a', 'e', 'c', 'd']

好像什么都没有发生~~

没关系,我们再来创建一个 tupple

>>> b=("a","b","c","d")

同样地,让我们将 tupple 中的 b 改成 e

>>> b[1]="2"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

为什么同样的赋值操作,在 tupple 中会出现错误呢?原因就是我们上面说到的 tupple 是不可变对象,创建之后不能修改

有个小伙伴看见了

然后给我写了一段下面的代码

>>> b=("a","b","c","d")
>>> b=("a","e","c","d")
>>>b
>>>("a","e","c","d")

这样子是不是做到了修改 tupple 中的第2个元素呢?答案是否定的,为什么呢?别着急往下看

可变对象和不可变对象

在开始下面的内容之前,需要牢记一句话,Python 中的变量是对在内存中 Python 对象的引用

以我们上面的列表 a 为例

>>> a = ["a","b","c","d"]

它在内存中实际表现如下图

如果需要获取列表 list 在内存的实际位置,我们可以借用内置函数 id()

>>> a=["a","b","c","d"]
>>> id(a)
4557552456

现在我们去修改一下 a[1] 的值,然后再用 id() 这个函数去获取 a 在内存的地址,你会发现它的值没有改变,仍然指向相同位置

>>> a[1] = "e"
>>> id(a)
4557552456

整个过程如下图

接下来我们看一下对 tupple 进行同样的操作会有什么变化

>>> a=("a","b","c","d")
>>> id(a)
4557412296
>>> a=("a","e","c","d")
>>> id(a)
4557586504

不难发现,再修改之后指向内存中的地址发生了改变,这意味着这个时候变量 a 指向了一个全新的对象。

如果觉得难以理解,没有关系,看下面的图

这个时候如果没有其它变量指向之前的 tupple,Python 的 GC 将会把旧的 tupple 从内存中完全删除.

为什么需要 list 和 tupple ?

其实更贴切的应该问,为什么需要可变对象和不可变对象呢?

  1. 添加元素效率

从上面的内容,我们知道一旦创建了 tupple,这个时候任何修改操作都会去创建新的对象,然后变量重新指向新的对象,假设添加的元素足够多,其效率可想而知。这里的添加是指如下的操作( tupple 本身没有添加的方法)

a = ()
for i in range(num):
a = a + (i,)
  1. debugger 难度

在之前的 [直接赋值,深拷贝和浅拷贝] 中提到可变对象,修改赋值后的变量,会对原有的变量造成影响,会导致其 value 值的改变,在实际开发过程中很容易被忽略

>>> a = [1, 3, 5, 7]
>>> b = a
>>> b[0] = -10
>>> a
[-10, 3, 5, 7]

什么时候去使用 tupple 和 list

总结一下,list 和 tupple 的使用场景

  1. tupple 不存在添加和删除的操作,更不存在修改的操作,如果有这些需求,不用使用 tupple,去用 list
  2. 如果只是遍历的话, tupple 的速度是比 list 要快的
  3. 如果你有些数据是需要写保护,不希望在运行过程中被修改的话,用 tupple
  4. tupple 可以用来做 dict 的 key 的,准确的说,所有不可变对象都可以,而 list 不可以

参考

https://learnbatta.com/blog/why-tuple-is-faster-than-list-in-python-22/

https://www.afternerd.com/blog/difference-between-list-tuple/

https://www.programiz.com/python-programming/list-vs-tuples

[Python] list vs tupple的更多相关文章

  1. python基础-2 编码转换 pycharm 配置 运算符 基本数据类型int str list tupple dict for循环 enumerate序列方法 range和xrange

    1.编码转换 unicode 可以编译成 UTF-U GBK 即 #!/usr/bin/env python # -*- coding:utf-8 -*- a = '测试字符' #默认是utf-8 a ...

  2. python使用总结

    近来公司的测试部门要我们开发,按他们给我测试案例,写vba脚本,方便他们做自动化测试,老大把这事交给了我做.之前没写过vba,很多API都不会用,边写边谷歌,写得很慢. 我记得测试第一次做的是打开关闭 ...

  3. python之路 目录

    目录 python python_基础总结1 python由来 字符编码 注释 pyc文件 python变量 导入模块 获取用户输入 流程控制if while python 基础2 编码转换 pych ...

  4. Python递归遍历目录下所有文件

    #自定义函数: import ospath="D:\\Temp_del\\a"def gci (path): """this is a stateme ...

  5. 转 python 之 分割参数getopt

    python 之 分割参数getopt os下有个方法walk,非常的好用,用来生成一个generator.每次可以得到一个三元tupple,其中第一个为起始路径,第二个为起始路径下的文件夹,第三个是 ...

  6. python文件和文件夹訪问File and Directory Access

    http://blog.csdn.net/pipisorry/article/details/47907589 os.path - Common pathname manipulations 都是和路 ...

  7. python新手菜鸟之基础篇

    s=0 for i in range(1,101): s += i else: print(s) def main(n): '''打印菱形图形''' for i in range(n): print( ...

  8. 一起学Python——数据类型详解

    和学习其他编程语言一样,首先要了解一门语言的数据类型. Python的数据类型有整型.浮点型.字符串.布尔型.日期时间类型.list列表.set集合.tuple元组.dict词典等. 1.整型 就是数 ...

  9. Python:遍历一个目录下所有的文件及文件夹,然后计算每个文件的字符和line的小程序

    编写了一个遍历一个目录下所有的文件及文件夹,然后计算每个文件的字符和line的小程序,先把程序贴出来. #coding=utf-8 ''' Created on 2014年7月14日 @author: ...

随机推荐

  1. Java实现LeetCode_0007_ReverseInteger

    package javaLeetCode_primary; import java.util.Scanner; /** * Given a 32-bit signed integer, reverse ...

  2. java实现Prim算法

    1 问题描述 何为Prim算法? 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex ...

  3. Java实现信用卡校验

    当你输入信用卡号码的时候,有没有担心输错了而造成损失呢?其实可以不必这么担心,因为并不是一个随便的信用卡号码都是合法的,它必须通过Luhn算法来验证通过. 该校验的过程: 1.从卡号最后一位数字开始, ...

  4. Java实现第九届蓝桥杯书号验证

    书号验证 2004年起,国际ISBN中心出版了<13位国际标准书号指南>. 原有10位书号前加978作为商品分类标识:校验规则也改变. 校验位的加权算法与10位ISBN的算法不同,具体算法 ...

  5. PAT 科学计数法

    科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式 [+-][1-9].[0-9]+E[+-][0-9]+,即数字的整数部分只有 1 位,小数部分至少有 1 位,该数字及其指 ...

  6. CGLIB动态代理机制,各个方面都有写到

    CGLIB库介绍 代理提供了一个可扩展的机制来控制被代理对象的访问,其实说白了就是在对象访问的时候加了一层封装.JDK从1.3版本起就提供了一个动态代理,它使用起来非常简单,但是有个明显的缺点:需要目 ...

  7. iOS-Code Data的快速体验

    Code Data Core Data 是iOS SDK 里的一个很强大的框架,允许程序员以面向对象的方式储存和管理数据.使用Core Data框架,程序员可以很轻松有效地通过面向对象的接口管理数据 ...

  8. 需要加token验证的接口返回文件流下载

    没有加token之前,下载文件用的是a标签,直接下载. 现在要求是需要在header中加入token. getDownload(urls, fileName) { var url = urls; va ...

  9. python 直方图

    import matplotlib.pyplot as plt import numpy as np pop = np.random.randint(0,100,100) pop n,bins,pat ...

  10. @codefoces - 566E@ Restoring Map

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 对于一棵 n 个点的树,我们称两个点是相邻的当且仅当两个点的距离 ...