文章目录

  • 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游戏开发 小甲鱼python最新版_小甲鱼python游戏开发


序列是Python中最基本的数据结构。序列中的每个元素都分配一个数字 - 它的位置,或叫索引。第一个索引是0,第二个索引是1,依此类推。(或者从后往前算的话,最后一个元素的索引值是-1,倒数第二个是-2,依此类推)

1.访问列表

前面学过的字符串就是一个序列,而这里的列表也是一个序列。所以对于访问列表也可以用for循环,如下:

小甲鱼python游戏开发 小甲鱼python最新版_小甲鱼python游戏开发_02


如果单单想访问列表中的某一个元素,则可以使用索引来访问,如下:

小甲鱼python游戏开发 小甲鱼python最新版_小甲鱼python游戏开发_03

2.列表切片

小甲鱼python游戏开发 小甲鱼python最新版_浅拷贝_04


小甲鱼python游戏开发 小甲鱼python最新版_深拷贝_05

3.列表的增删改查

列表与字符串不同,它不是成不变的。

0.增

0.append方法

append()方法:在列表末尾添加一个指定元素。

小甲鱼python游戏开发 小甲鱼python最新版_嵌套_06

1.extend()方法

extend()方法:在列表末尾一次性追加另一个可迭代对象中的多个值(新的内容是追加到原列表的最后一个元素后面)。

小甲鱼python游戏开发 小甲鱼python最新版_浅拷贝_07

2.使用切片也可以达到以上两个方法的效果:

小甲鱼python游戏开发 小甲鱼python最新版_嵌套_08

3.insert()方法

insert()方法:在列表任意位置添加数据。

小甲鱼python游戏开发 小甲鱼python最新版_python_09

1.删

0.remove()方法

remove()方法:删除列表中指定元素(如果存在多个匹配的元素,那么它只会删除第一个;指定元素不存在则报错)。

小甲鱼python游戏开发 小甲鱼python最新版_小甲鱼python游戏开发_10

1.pop()方法

pop()方法:删除某个位置上的元素,如果不指定参数的话,默认删除列表的最后一个元素。

小甲鱼python游戏开发 小甲鱼python最新版_嵌套_11

2.clear()方法

clear()方法:将列表清空。需要注意的是:列表只是清空变成一个空列表而已,列表仍然还在!

小甲鱼python游戏开发 小甲鱼python最新版_浅拷贝_12

2.改

0.修改某一个值

小甲鱼python游戏开发 小甲鱼python最新版_小甲鱼python游戏开发_13

1.使用切片批量修改

小甲鱼python游戏开发 小甲鱼python最新版_嵌套_14


以上代码实质上是要分两个步骤来实现的:

1)将赋值号(=)左边指定的内容删除;

2)将包含在赋值号(=)右边的可迭代对象中的片段插入左边被删除的位置。

3.插曲——列表排序

小甲鱼python游戏开发 小甲鱼python最新版_浅拷贝_15


sort()方法中有一个参数是reverse,其默认为False,所以默认为升序排序,若将其指定为False,则为降序排序,如下:

小甲鱼python游戏开发 小甲鱼python最新版_浅拷贝_16

4.查

0.count()方法

count()方法:查列表中指定某元素出现的次数。

小甲鱼python游戏开发 小甲鱼python最新版_嵌套_17

1.index()方法

index()方法:查找某个元素的索引值,传入的参数是需要查找的元素,也可指定查找列表的起始位置(若有多个相同元素,其返回的是第一个找到的元素的索引值)。

小甲鱼python游戏开发 小甲鱼python最新版_浅拷贝_18

4.拷贝列表

0.copy()方法

小甲鱼python游戏开发 小甲鱼python最新版_小甲鱼python游戏开发_19

1.使用切片

小甲鱼python游戏开发 小甲鱼python最新版_嵌套_20


注意:以上两种拷贝列表的方法都是浅拷贝!

1.列表的加法和乘法

0. 加法

列表的加法其实就是拼接列表,相加的对象都需要是列表才行,如下:

小甲鱼python游戏开发 小甲鱼python最新版_小甲鱼python游戏开发_21

1. 乘法

列表的乘法其实就是重复列表内的所有元素若干次形成新的列表。

小甲鱼python游戏开发 小甲鱼python最新版_嵌套_22

2.嵌套列表

  1. 嵌套列表,顾名思义,就是在列表中嵌入列表作为元素。如下:
  2. 访问嵌套列表
  • 访问所有元素(通过嵌套循环)
  • 访问某个元素(通过下标索引)
  • 同样,也可以用乘法+循环的方式创建嵌套列表,如下:

小甲鱼python游戏开发 小甲鱼python最新版_浅拷贝_23


那为何不直接这么写呢?如下:

小甲鱼python游戏开发 小甲鱼python最新版_嵌套_24


试着改变一下列表A、B中某一个列表的某一元素的值:

小甲鱼python游戏开发 小甲鱼python最新版_python_25


小甲鱼python游戏开发 小甲鱼python最新版_嵌套_26


为啥A和B的结果不一样呢?

插曲——运算符is

is运算符也被称之为同一性运算符,用于检验两个变量是否指向同一个对象。

举例如下:

小甲鱼python游戏开发 小甲鱼python最新版_小甲鱼python游戏开发_27


Pytho对于不同对象的存储机制并不一样。由于字符串是不可变的,所以其只需要在内存中开辟一个位置来存放即可,所以当有多个变量名指向同一个字符串,比如上面的x,y ,那它们的关系图如下:

小甲鱼python游戏开发 小甲鱼python最新版_小甲鱼python游戏开发_28


而列表是可变的,所以尽管以上x,y两个列表的内容一样,但是Python还是要为其开辟两个不同的位置进行存放。回到刚刚的列表A = [[0, 0, 0], [0, 1, 0], [0, 0, 0]]和列表B = [[0, 0, 0], [0, 1, 0], [0, 0, 0]],检验一下:

小甲鱼python游戏开发 小甲鱼python最新版_小甲鱼python游戏开发_29


由上可知A的三个列表元素都不是同一个对象,而B的三个列表元素都是同一个元素。两个列表在内存中的布局如下:

小甲鱼python游戏开发 小甲鱼python最新版_python_30


B的问题在于试图用乘号完成对一个列表的拷贝,但是其拷贝的只是同一个列表的引用(内存地址),所以才会有上面的"牵一发而动全身"。所以创建多维列表不能这么来!!!

3.浅拷贝和深拷贝

0.引用

在Python中,变量不是一个盒子,当赋值运算发生的时候,Python不是将数据放在变量中,而是放在内存中,将一个变量赋值给另一个变量其实就是将一个变量的引用(内存地址)传递给另一个变量,如下:

小甲鱼python游戏开发 小甲鱼python最新版_浅拷贝_31

1. 浅拷贝

对于列表的浅拷贝,可以用copy()方法,也可以用切片。如下:

小甲鱼python游戏开发 小甲鱼python最新版_浅拷贝_32


小甲鱼python游戏开发 小甲鱼python最新版_嵌套_33


浅拷贝,指的是重新分配一块内存,创建一个新的对象,但里面的若有子对象则他们的子对象还是指向同一对象(就是引用)。这里原对象中没有子对象,所以此时x和y已经指向完全不同的对象了,所以改变x对y产生影响。

小甲鱼python游戏开发 小甲鱼python最新版_深拷贝_34


但如果存在子对象(可变对象),浅拷贝通常会出现一些问题情况,如下嵌套列表的浅拷贝:

小甲鱼python游戏开发 小甲鱼python最新版_深拷贝_35


发现使用copy()方法拷贝x,改变x中列表元素的值,y中的也会相应改变,这是因为浅拷贝只是拷贝了外层的父对象,如果包含子对象(可变元素)的话,那么拷贝的只是其引用。具体如下图:

小甲鱼python游戏开发 小甲鱼python最新版_小甲鱼python游戏开发_36


此时,要解决这一问题就要用到深拷贝!

2.深拷贝

深拷贝:是指重新分配一块内存,创建一个新的对象,并且将原对象中的元素,以递归的方式,通过创建新的子对象拷贝到新对象中(即完全拷贝了父对象及其子对象)。 因此,新对象和原对象没有任何关联。

copy模块

实现深拷贝,需要借助copy模块,这模块有两个函数copy()和deepcopy(),前者是实现浅拷贝,后者是实现深拷贝。例子如下:

小甲鱼python游戏开发 小甲鱼python最新版_小甲鱼python游戏开发_37


小甲鱼python游戏开发 小甲鱼python最新版_深拷贝_38


深拷贝具体如下图:

小甲鱼python游戏开发 小甲鱼python最新版_小甲鱼python游戏开发_39

4.列表推导式

0.例子引入

问题:请问如何将列表中的元素的值都变成原来的2倍呢?

最先想到的就是用循环,在循环中逐一更新列表各个元素的值:

小甲鱼python游戏开发 小甲鱼python最新版_浅拷贝_40


但是使用列表推导式,即可以少些代码,也可以提高程序的执行效率(通常比循环快一倍左右),如下:

小甲鱼python游戏开发 小甲鱼python最新版_小甲鱼python游戏开发_41


但是这两种方式从根本上并不是完全一样的,循环是通过迭代来逐个修改原列表中的元素,而列表推导式则是直接创建一个新的列表,再赋值给原先的变量名。

1.列表推导式的语法

列表推导式的语法:[expression for target in iterable] 举例:

小甲鱼python游戏开发 小甲鱼python最新版_深拷贝_42


以上其实和循环创建列表式是一样的,但是简便了超级多!

2.看下字符串的几个例子

小甲鱼python游戏开发 小甲鱼python最新版_浅拷贝_43

3.看下嵌套列表的几个例子

小甲鱼python游戏开发 小甲鱼python最新版_嵌套_44

4.利用列表推导式创建嵌套列表

前面我们发现列表创建得通过循环,其实列表推导式也可以很方便地创建列表,如下:

小甲鱼python游戏开发 小甲鱼python最新版_深拷贝_45

5.高级一点的列表推导式

0.带有if语句的列表推导式

语法结构:expression for target in iterable if condition 举例(执行顺序如下序号):

小甲鱼python游戏开发 小甲鱼python最新版_小甲鱼python游戏开发_46


小甲鱼python游戏开发 小甲鱼python最新版_深拷贝_47

1.实现嵌套的列表推导式

语法结构:

[expression for target1 in iterable1
			for target2 in iterable2
			..
			for target in iterableN]

嵌套的列表推导式对应嵌套循环(用嵌套循环来理解就很容易啦~)

举例:

小甲鱼python游戏开发 小甲鱼python最新版_浅拷贝_48

2.最高级的列表推导式

语法结构:

[expression for target1 in iterable1 if condition1
			for target2 in iterable2 if condition2
			..
			for target in iterableN if conditionN]

举例:

小甲鱼python游戏开发 小甲鱼python最新版_python_49


等价于如下循环:

小甲鱼python游戏开发 小甲鱼python最新版_深拷贝_50

5.程序设计原则——“KISS”

KISS——Keep It Simple $ Stupid
对于列表推导式的使用要把握好一定的度,虽然列表推导式比一般的循环效率高且写起来代码也少,但是过于复杂的列表推导式会增加后期阅读和维护代码的成本,所以需要恰当使用!