文章目录
- 0.列表
- 0.创建列表
- 1.访问列表
- 2.列表切片
- 3.列表的增删改查
- 0.增
- 0.append方法
- 1.extend()方法
- 2.使用切片也可以达到以上两个方法的效果:
- 3.insert()方法
- 1.删
- 0.remove()方法
- 1.pop()方法
- 2.clear()方法
- 2.改
- 0.修改某一个值
- 1.使用切片批量修改
- 3.插曲——列表排序
- 4.查
- 0.count()方法
- 1.index()方法
- 4.拷贝列表
- 0.copy()方法
- 1.使用切片
- 1.列表的加法和乘法
- 0. 加法
- 1. 乘法
- 2.嵌套列表
- 插曲——运算符is
- 3.浅拷贝和深拷贝
- 0.引用
- 1. 浅拷贝
- 2.深拷贝
- copy模块
- 4.列表推导式
- 0.例子引入
- 1.列表推导式的语法
- 2.看下字符串的几个例子
- 3.看下嵌套列表的几个例子
- 4.利用列表推导式创建嵌套列表
- 5.高级一点的列表推导式
- 0.带有if语句的列表推导式
- 1.实现嵌套的列表推导式
- 2.最高级的列表推导式
- 5.程序设计原则——“KISS”
0.列表
列表是最常用的Python数据类型,它可以作为一个方括号内的逗号分隔值出现。列表可以容纳不同类型的数据。
0.创建列表
创建一个列表,只要把逗号分隔各个元素,并使用方括号括起来即可。如下所示:
序列是Python中最基本的数据结构。序列中的每个元素都分配一个数字 - 它的位置,或叫索引。第一个索引是0,第二个索引是1,依此类推。(或者从后往前算的话,最后一个元素的索引值是-1,倒数第二个是-2,依此类推)
1.访问列表
前面学过的字符串就是一个序列,而这里的列表也是一个序列。所以对于访问列表也可以用for循环,如下:
如果单单想访问列表中的某一个元素,则可以使用索引来访问,如下:
2.列表切片
3.列表的增删改查
列表与字符串不同,它不是成不变的。
0.增
0.append方法
append()方法:在列表末尾添加一个指定元素。
1.extend()方法
extend()方法:在列表末尾一次性追加另一个可迭代对象中的多个值(新的内容是追加到原列表的最后一个元素后面)。
2.使用切片也可以达到以上两个方法的效果:
3.insert()方法
insert()方法:在列表任意位置添加数据。
1.删
0.remove()方法
remove()方法:删除列表中指定元素(如果存在多个匹配的元素,那么它只会删除第一个;指定元素不存在则报错)。
1.pop()方法
pop()方法:删除某个位置上的元素,如果不指定参数的话,默认删除列表的最后一个元素。
2.clear()方法
clear()方法:将列表清空。需要注意的是:列表只是清空变成一个空列表而已,列表仍然还在!
2.改
0.修改某一个值
1.使用切片批量修改
以上代码实质上是要分两个步骤来实现的:
1)将赋值号(=)左边指定的内容删除;
2)将包含在赋值号(=)右边的可迭代对象中的片段插入左边被删除的位置。
3.插曲——列表排序
sort()方法中有一个参数是reverse,其默认为False,所以默认为升序排序,若将其指定为False,则为降序排序,如下:
4.查
0.count()方法
count()方法:查列表中指定某元素出现的次数。
1.index()方法
index()方法:查找某个元素的索引值,传入的参数是需要查找的元素,也可指定查找列表的起始位置(若有多个相同元素,其返回的是第一个找到的元素的索引值)。
4.拷贝列表
0.copy()方法
1.使用切片
注意:以上两种拷贝列表的方法都是浅拷贝!
1.列表的加法和乘法
0. 加法
列表的加法其实就是拼接列表,相加的对象都需要是列表才行,如下:
1. 乘法
列表的乘法其实就是重复列表内的所有元素若干次形成新的列表。
2.嵌套列表
- 嵌套列表,顾名思义,就是在列表中嵌入列表作为元素。如下:
- 访问嵌套列表
- 访问所有元素(通过嵌套循环)
- 访问某个元素(通过下标索引)
- 同样,也可以用乘法+循环的方式创建嵌套列表,如下:
那为何不直接这么写呢?如下:
试着改变一下列表A、B中某一个列表的某一元素的值:
为啥A和B的结果不一样呢?
插曲——运算符is
is运算符也被称之为同一性运算符,用于检验两个变量是否指向同一个对象。
举例如下:
Pytho对于不同对象的存储机制并不一样。由于字符串是不可变的,所以其只需要在内存中开辟一个位置来存放即可,所以当有多个变量名指向同一个字符串,比如上面的x,y ,那它们的关系图如下:
而列表是可变的,所以尽管以上x,y两个列表的内容一样,但是Python还是要为其开辟两个不同的位置进行存放。回到刚刚的列表A = [[0, 0, 0], [0, 1, 0], [0, 0, 0]]和列表B = [[0, 0, 0], [0, 1, 0], [0, 0, 0]],检验一下:
由上可知A的三个列表元素都不是同一个对象,而B的三个列表元素都是同一个元素。两个列表在内存中的布局如下:
B的问题在于试图用乘号完成对一个列表的拷贝,但是其拷贝的只是同一个列表的引用(内存地址),所以才会有上面的"牵一发而动全身"。所以创建多维列表不能这么来!!!
3.浅拷贝和深拷贝
0.引用
在Python中,变量不是一个盒子,当赋值运算发生的时候,Python不是将数据放在变量中,而是放在内存中,将一个变量赋值给另一个变量其实就是将一个变量的引用(内存地址)传递给另一个变量,如下:
1. 浅拷贝
对于列表的浅拷贝,可以用copy()方法,也可以用切片。如下:
浅拷贝,指的是重新分配一块内存,创建一个新的对象,但里面的若有子对象则他们的子对象还是指向同一对象(就是引用)。这里原对象中没有子对象,所以此时x和y已经指向完全不同的对象了,所以改变x对y产生影响。
但如果存在子对象(可变对象),浅拷贝通常会出现一些问题情况,如下嵌套列表的浅拷贝:
发现使用copy()方法拷贝x,改变x中列表元素的值,y中的也会相应改变,这是因为浅拷贝只是拷贝了外层的父对象,如果包含子对象(可变元素)的话,那么拷贝的只是其引用。具体如下图:
此时,要解决这一问题就要用到深拷贝!
2.深拷贝
深拷贝:是指重新分配一块内存,创建一个新的对象,并且将原对象中的元素,以递归的方式,通过创建新的子对象拷贝到新对象中(即完全拷贝了父对象及其子对象)。 因此,新对象和原对象没有任何关联。
copy模块
实现深拷贝,需要借助copy模块,这模块有两个函数copy()和deepcopy(),前者是实现浅拷贝,后者是实现深拷贝。例子如下:
深拷贝具体如下图:
4.列表推导式
0.例子引入
问题:请问如何将列表中的元素的值都变成原来的2倍呢?
最先想到的就是用循环,在循环中逐一更新列表各个元素的值:
但是使用列表推导式,即可以少些代码,也可以提高程序的执行效率(通常比循环快一倍左右),如下:
但是这两种方式从根本上并不是完全一样的,循环是通过迭代来逐个修改原列表中的元素,而列表推导式则是直接创建一个新的列表,再赋值给原先的变量名。
1.列表推导式的语法
列表推导式的语法:[expression for target in iterable]
举例:
以上其实和循环创建列表式是一样的,但是简便了超级多!
2.看下字符串的几个例子
3.看下嵌套列表的几个例子
4.利用列表推导式创建嵌套列表
前面我们发现列表创建得通过循环,其实列表推导式也可以很方便地创建列表,如下:
5.高级一点的列表推导式
0.带有if语句的列表推导式
语法结构:expression for target in iterable if condition
举例(执行顺序如下序号):
1.实现嵌套的列表推导式
语法结构:
[expression for target1 in iterable1
for target2 in iterable2
..
for target in iterableN]
嵌套的列表推导式对应嵌套循环(用嵌套循环来理解就很容易啦~)
举例:
2.最高级的列表推导式
语法结构:
[expression for target1 in iterable1 if condition1
for target2 in iterable2 if condition2
..
for target in iterableN if conditionN]
举例:
等价于如下循环:
5.程序设计原则——“KISS”
KISS——Keep It Simple $ Stupid
对于列表推导式的使用要把握好一定的度,虽然列表推导式比一般的循环效率高且写起来代码也少,但是过于复杂的列表推导式会增加后期阅读和维护代码的成本,所以需要恰当使用!