Python 修仙修炼录 07:列表灵囊,收纳万千数据
目录一、核心区别可变 vs 不可变二、列表List全用法1. 创建列表2. 访问/修改列表元素下标/索引3. 切片操作高效截取列表片段4. 遍历列表逐个访问元素5. 列表元素增删查新增元素查找元素删除元素6. 列表拼接三、元组Tuple全用法1. 创建元组2. 元组支持的操作只读3. 元组的隐藏用法多元赋值四、为什么有了列表还要元组五、快速总结一、核心区别可变 vs 不可变首先变量就是内存空间用来表示/存储数据python中列表和元组就是这样的机制可以用一个变量来表示很多个数据其实列表就类似于其他编程语言中的“数组”其次列表和元组的用法高度相似最本质、最关键的区别只有一点列表List可变类型创建完成后随时可以修改、添加、删除内部元素。元组Tuple不可变类型创建完成后无法修改、添加、删除元素。如果想改变内容要想改只能丢弃旧的搞个新的这个区别决定了它们的使用场景我们后文会详细说明。二、列表List全用法列表是 Python 中最常用的序列类型使用方括号[]表示。1. 创建列表Python 提供了 4 种创建列表的方式灵活适配不同场景# 1. 创建空列表字面值方式a[]print(type(a))# 输出class list# 2. 创建空列表内置函数 list() 方式blist()print(type(b))# 输出class list# 3. 创建带初始值的列表a[1,2,3,4]print(a)# 输出[1, 2, 3, 4]# 4. 列表支持存储任意类型数据数字、字符串、布尔值、甚至嵌套列表a[1,hello,True,[2,3,4]]print(a)# 输出[1, hello, True, [2, 3, 4]]C / Java 里面要求一个数组里只能存相同类型的变量2. 访问/修改列表元素下标/索引列表中的元素按顺序排列每个元素对应一个下标索引下标从 0 开始通过下标可以精准获取/修改元素。a[1,2,3,4]# 1. 通过下标访问元素print(a[2])# 输出3下标2对应第三个元素# 2. 通过下标修改元素列表可变的核心体现a[2]100print(a)# 输出[1, 2, 100, 4]# 3. 超出有效下标范围会报错# a[100] 100 # 报错IndexError# 4. 内置函数 len() 获取列表长度元素个数print(len(a))# 输出4# 5. 支持负下标其实等价于len(a) -1,-1 表示最后一个元素-2 表示倒数第二个以此类推print(a[len(a)-1])# 输出4print(a[-1])# 输出4print(a[-2])# 输出100Java中不能出现负数3. 切片操作高效截取列表片段切片是 Python 非常强大的特性用于快速截取列表的一部分语法列表[起始下标:结束下标:步长]规则包含起始下标不包含结束下标左闭右开区间[起始, 结束)切片下标越界不会报错会自动截取有效范围a[1,2,3,4,5,6,7,8,9,0]# 1. 基础切片取下标1~3的元素不包含3print(a[1:3])# 输出[2, 3]# 2. 省略边界print(a[1:])# 从下标1取到末尾[2,3,4,5,6,7,8,9,0]print(a[:2])# 从开头取到下标2[1,2]print(a[:-1])# 取到倒数第一个元素[1,2,3,4,5,6,7,8,9]print(a[:])# 截取整个列表[1,2,3,4,5,6,7,8,9,0]# 3. 指定步长每隔 n-1 个元素取一个print(a[::1])# 步长1全量元素print(a[::2])# 步长2取奇数位[1,3,5,7,9]print(a[::-1])# 步长-1倒序排列[0,9,8,7,6,5,4,3,2,1]# 4. 下标越界自动截取有效范围print(a[1:100])# 输出[2,3,4,5,6,7,8,9,0]小贴士切片操作是一个比较高效的操作进行切片的时候只是取出了原有列表中的一个部分并不涉及到“数据的拷贝”假设有一个很大的列表进行切片切片的范围也很大即使如此切片操作仍然非常高效.4. 遍历列表逐个访问元素遍历是列表最常用的操作Python 提供 3 种简洁的遍历方式a[1,2,3,4]# 1. for...in 直接遍历元素最推荐forelemina:print(elem)# 2. for 循环 下标遍历foriinrange(len(a)):print(a[i])# 3. while 循环 下标遍历i0whileilen(a):print(a[i])i15. 列表元素增删查列表是可变的支持灵活的增、删、查操作新增元素a[1,2,3,4]# 1. append()在列表末尾添加元素a.append(5)a.append(hello)print(a)# [1,2,3,4,5,hello]# 2. insert(下标, 元素)在指定下标位置插入元素a.insert(1,python)# 下标1处插入print(a)# [1,python,2,3,4,5,hello]a.insert(100,test)# 下标越界自动插入末尾查找元素a[1,2,3,4]# 1. in / not in判断元素是否存在print(1ina)# 判断1 是否在 在的话True 不在的话Falseprint(10notina)# 判断1 是不否在 不在的话True 在的话False# 2. index(元素)查找元素下标不存在则报错,Java不同会抛出-1因为python本身就有负数下标print(a.index(2))# 输出1删除元素a[1,2,3,4]# 1. pop()删除末尾元素a.pop()print(a)# [1,2,3]# 2. pop(下标)删除指定下标元素a.pop(1)print(a)# [1,3]# 3. remove(元素值)按值删除第一个匹配的元素a[aa,bb,cc,dd]a.remove(cc)print(a)# [aa,bb,dd]6. 列表拼接将两个列表合并有 3 种方式性能和用法不同a[1,2,3,4]b[5,6,7,8]# 1. 号拼接生成新列表原列表不变cabprint(c)# [1,2,3,4,5,6,7,8]# 2. extend()把后一个列表拼接到前一个列表内部无返回值高效a.extend(b)print(a)# [1,2,3,4,5,6,7,8]# None 这是一个特殊的变量的值表示“啥都没有”extend方法其实是没有返回值的ca.extend(b)# None# None 非常类似于 c 里面的NULL或者 Java 里的 null# 3. 拼接等价于 a a babprint(a)虽然 extend() 和 都可以进行列表拼接但是还是存在区别的所以大数据量拼接用extend()效率最高无数据拷贝三、元组Tuple全用法元组的用法和列表几乎完全一致唯一区别是不可修改使用圆括号()表示。1. 创建元组# 1. 创建空元组a()btuple()print(type(a))# class tuple# 2. 创建带初始值的元组a(1,2,3,4)print(a)# (1,2,3,4)# 3. 支持任意类型数据a(1,hello,True,[1,2,3])2. 元组支持的操作只读元组只支持「读」操作不支持修改、添加、删除元素a(1,2,3,4)# 1. 下标访问print(a[1])# 2print(a[-1])# 4# 2. 切片操作print(a[1:3])# (2,3)# 3. 遍历forelemina:print(elem)# 4. 元素查找print(3ina)# Trueprint(a.index(3))# 2# 5. 元组拼接b(5,6,7,8)print(ab)# (1,2,3,4,5,6,7,8)# 6. 尝试修改直接报错# a[0] 100 # TypeError: tuple object does not support item assignment3. 元组的隐藏用法多元赋值Python 的多元赋值底层就是基于元组实现的# 函数返回多个值本质返回的是元组defget_point():x10y20returnx,y# 等价于 return (x,y)x,yget_point()print(type(get_point()))# class tuple四、为什么有了列表还要元组很多新手会疑惑用法差不多元组还不能修改为什么要设计它核心原因有 2 个代码安全协同开发必备如果你写的函数需要接收外部数据用元组做参数可以保证数据不会被意外修改。调用者无需担心自己的数据被篡改大大降低协作风险。协同开发的时候一个程序猿A实现一些功能提供给程序猿B来使A写好一些函数让B去调用函数肯定要传参B在传参的时候就可能会纠结一个问题:我把我的参数传过去了A的函数里面是否会把我的参数的内容给改了呢?如果使用的元组作为参数就可以避免这样的纠结元组不能修改不可变对象不可变对象可哈希元组是不可变对象可以作为字典的「键」也可以存入集合List 做不到。五、快速总结特性列表List元组Tuple符号[]()可变性可变增删改不可变只读性能灵活略低简洁高效适用场景数据需要频繁修改数据固定、保护数据核心方法append、insert、pop仅支持读操作列表[]可变支持增删改查适合需要动态修改的数据元组()不可变仅支持只读操作适合保护固定数据。下标、切片、遍历是两者通用的核心操作负下标和倒序切片是 Python 特色语法。元组的不可变性保障了数据安全是协同开发和固定配置的首选多元赋值底层依赖元组实现。