Python知识学习06——列表

(一)与Java列表的对比

列表类型:list

Java语言的数组:

1
int nums = {11, 22, 33, 44, 55}

Java列表的特点

  1. 数组内元素数据类型必须相同
  2. 数组长度固定

Python语言的列表:

1
a = [123, 1.23, "123", True]

Python列表的特点

  1. 列表内元素数据类型可以不同
  2. 列表长度不固定
  3. python列表不能指定初始化大小

(二)列表的索引

列表的index方法没有rindex,但是可以接收起始值,只能从左向右查

index和count方法的时间复杂度都是On,当index方法没有找到匹配元素时,将会报错

index方法

1
2
3
4
5
# 列表的index方法,返回第一个匹配的元素到索引
>>> lst = [1, 2, 1]
>>> lst.index(1)

0
1
2
3
4
5
# 列表的index方法,指定从哪个索引位置开始查找,还可以指定结束的索引,但是只能从左向右
>>> lst = [1, 2, 1]
>>> lst.index(1, -1)

2

count方法

1
2
3
4
5
# count方法,统计一个元素出现的总次数
>>> lst = [1, 2, 3, 4, 1]
>>> lst.count(1)

2

(三)列表的增删改查操作

增加

append方法,将元素添加在列表的最后

时间复杂度为O1,属于就地修改,返回值为None

1
2
3
>>> names = ["Tom", "Jerry", "Rose"]
>>> names.append("Peter")
['Tom', 'Jerry', 'Rose', 'Peter']

insert方法,将元素插入指定索引位置

insert也属于就地修改,返回值为None(索引可以溢出,过大则尾部追加,过小则头部追加)

1
2
3
>>> names = ["Tom", "Jerry", "Rose"]
>>> names.insert(1, "Peter")
['Tom', 'Peter', 'Jerry', 'Rose']

提示:insert()需要指定插入的索引位置(索引从0计),而append()固定添加在原有列表的最后

+/*方法

合并两个列表的方法:列表相加,产生一个新的列表,原列表保持不变

1
2
3
4
>>> names1 = ["Tom", "Jerry"]
>>> names2 = ["Peter", "Rpse"]
>>> names3 = names1 + names2
['Tom', 'Jerry', 'Peter', 'Rpse']

提示:列表也可以使用乘*n来重复列表元素n次,产生新列表,原列表保持不变

extend方法,将可迭代对象的元素追加进来,就地修改,返回None

将一个列表合到另一个列表当中:

1
2
3
4
5
>>> names1 = ["Tom", "Jerry"]
>>> names2 = ["Peter", "Rose"]
>>> names1.extend(names2)
# names1 ['Tom', 'Jerry', 'Peter', 'Rpse']
# names2 ['Peter', 'Rose']

提示:names1不仅拥有自己原本的元素,还继承了names2的元素

删除

按元素删除

remove()函数接收一个元素,并将该元素从列表中删除,返回值为None

1
2
3
>>> names = ["Tom", "Jerry", "Rose", "Tom"]
>>> names.remove("Tom")
# names ['Jerry', 'Rose', 'Tom']

按下标删除

pop()函数将列表最后一个元素删除,并返回该元素

pop(index)可以根据索引删除元素,并返回该元素

1
2
3
>>> names = ["Tom", "Jerry", "Rose"]
>>> names.pop()
'Rose'

提示:从左到右删除第一个匹配的元素

使用切片

使用下标获取列表元素,以及切片

1
2
3
>>> names = ["Tom", "Jerry", "Rose", "Tom"]
>>> names[0]
'Tom'
1
2
3
>>> names = ["Tom", "Jerry", "Rose", "Tom"]
>>> names[1: 3]
['Jerry', 'Rose']

使用del关键字,根据下标删除元素:

1
2
3
>>> names = ["Tom", "Jerry", "Rose", "Tom"]
>>> del names[0]
['Jerry', 'Rose', 'Tom']

使用clear清除元素

clear()可以清空一个列表内的所以元素

修改

改变元素

1
2
3
>>> names = ["Tom", "Jerry", "Rose", "Tom"]
>>> names[0] = "Tommy"
# names ['Tommy', 'Jerry', 'Rose', 'Tom']

列表的反转(倒序排列)

就地修改,返回None

1
2
3
4
>>> lst = [1, 2, 3]
>>> lst.reverse()

[3, 2, 1]

列表的排序

sort(key = None, reverse = False) -> None

排序函数,就地修改,默认为升序,key接收一个排序函数

查询

1
2
3
4
5
names = ["Tom", "Jerry", "Rose"]
if "Jerry" in names:
print("找到了")
elif "Jerry" not in names:
print("未找到")

查询获取目标对象的索引

1
2
3
names = ["Tom", "Peter", "Rose"]
index = names.index("Peter")
print(index)

(四)拓展:列表的复制及比较

列表复制

copy()方法可以复制列表的元素,赋值给新的变量,但是不是同一个对象

1
2
3
4
5
6
7
>>> lst1 = [1, 2, 3]
>>> lst2 = lst1.copy()
>>> print(lst1 == lst2)
>>> print(lst1 is lst2)

True
False

小练习01

已知代码如下,问:

  • lst1 == lst2结果是什么
  • 如何比较lst1和lst2的内存地址
1
2
lst1 = list(range(4))
lst2 = list(range(4))
  • 如果再执行以下语句,是否发生列表复制的过程?
1
lst1 = lst2
  • 如果再执行以下语句,求输出结果
1
2
lst1[0] = 99
print(lst2[0])

答:

  • lst1 == lst2,返回True,因为在Python中,双等号是依次比较列表元素是否相同
  • 我们可以通过id(lst1)id(lst2)来分别获取两个列表的相对内存地址,比较其是否为相同对象;或者直接使用lst1 is lst2来进行比较;注意,列表不可求hash()
  • 不存在列表复制,而是指向的内存地址的更改
  • 输出99,因为此时,lst1lst2已经指向相同内存,为同一对象

小练习02

已知如下代码,请写出输出结果:

1
2
3
4
5
6
7
8
lst1 = [1, 2, 3, [55, 88, 99], 4]
lst2 = lst1.copy()

lst2[1] = 22
lst2[3][0] = 555

print(lst1[1])
print(lst1[3][0])

1
2
2
555

原因分析:

我们都知道,copy()方法是复制列表中的元素,所以乍一看下,lst1的子列表中的元素不应该跟随lst2的子列表元素一起更改。但是,由于lst1中的子列表是引用类型,当执行copy()`lst1操作的时候,并不会将子列表中的元素也一起拷贝,而是拷贝了子列表的内存地址,这被称作浅拷贝`

浅拷贝:

只拷贝父对象,不会拷贝对象的内部的子对象

解决

使用深拷贝

1
2
3
4
5
6
7
8
9
10
import copy

lst1 = [1, 2, 3, [55, 88, 99], 4]
lst2 = copy.deepcopy(lst1)

lst2[1] = 22
lst2[3][0] = 555

print(lst1[1])
print(lst1[3][0])

输出:

1
2
2
55