学习python的第八天之数据类型——list列表
学习python的第八天之数据类型——list列表
Python 中的列表(list)是一种基本的数据结构,它可以包含零个或多个元素,这些元素可以是不同类型的。列表是可变的(mutable),这意味着我们可以在创建列表后添加、删除或更改其元素。
支持的数据类型:
int
,str
,float
,bool
,complex
,list
,dictionary
,tuple
,set
特点:
- 没有长度限制
- 可以存放任意类型
创建列表
创建列表最简单的方式是使用方括号
[]
,并将元素用逗号,
分隔开来。
my_list = [1, 2, 3]
print(my_list) # 输出: [1, 2, 3]
# 可以包含不同类型的元素
my_list = [1, 'Hello', 3.14, True, 3+4j, [1,2], {'1':'one', '2':'two'}, (3, 4), {5, 6}]
print(my_list) # 输出: [1, 'Hello', 3.14, True, 3+4j, [1,2], {'1':one, '2':two}, (3, 4), {5, 6}]
# 空列表
empty_list1 = []
empty_list2 = list()
print(empty_list1) # 输出: []
print(empty_list2) # 输出: []
访问列表元素
可以通过索引(indexing)来访问列表中的元素。在 Python 中,索引是从 0 开始的。
my_list = ['a', 'b', 'c', 'd']
print(my_list[0]) # 输出: 'a'
print(my_list[1]) # 输出: 'd'
# 使用负数索引从列表末尾开始访问
print(my_list[-1]) # 输出: 'd'
print(my_list[-2]) # 输出: 'c'
列表切片
切片(slicing)允许我们获取列表的一个片段。使用切片时,需要指定开始索引和结束索引,格式为
list[start:end:step]
。请注意,返回的切片会包含开始索引处的元素,但不包含结束索引处的元素。
# 创建一个列表
my_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 获取索引2到索引5之间的元素(不包括索引5)
sublist = my_list[2:5]
print(sublist) # 输出: [2, 3, 4]
# 获取从索引0到索引4之间的元素,每隔2个取一个
sublist = my_list[0:5:2]
print(sublist) # 输出: [0, 2, 4]
# 获取从索引3开始到末尾的元素
sublist = my_list[3:]
print(sublist) # 输出: [3, 4, 5, 6, 7, 8, 9]
# 获取从开始到索引7(不包括)的元素,每隔3个取一个
sublist = my_list[:7:3]
print(sublist) # 输出: [0, 3, 6]
# 获取列表的所有元素,但是倒序(步长为-1)
reversed_list = my_list[::-1]
print(reversed_list) # 输出: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
# 获取列表的所有元素(相当于复制了一个列表)
copy_list = my_list[:]
print(copy_list) # 输出: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
在Python中,
copy_list = my_list[:]
和copy_list = my_list
有着本质的区别。
copy_list = my_list[:]
这种方式是通过切片操作来创建
my_list
的一个浅拷贝。虽然copy_list
和my_list
中的元素是对相同对象的引用(对于可变对象来说,这意味着改变其中一个列表中的可变元素会影响到另一个列表中的对应元素),但copy_list
本身是一个新的列表对象。因此,如果你对copy_list
进行添加、删除或修改其元素的操作,这些操作不会影响到my_list
。
copy_list = my_list
这种方式并没有创建
my_list
的拷贝,而是让copy_list
和my_list
指向同一个列表对象。这意味着,任何对copy_list
的修改都会直接反映到my_list
上,反之亦然。它们实际上是同一个列表的两个不同名字。
# 创建一个列表
my_list = [1, 2, 3, [4, 5]]
# 使用切片操作创建浅拷贝
copy_list_slice = my_list[:]
# 直接赋值,不创建新列表
copy_list_reference = my_list
# 查看这三个变量地址是否相同
print(id(my_list), id(copy_list_slice), my_list is copy_list_slice)
# 2400423854016 2400459678848 False
print(id(my_list), id(copy_list_reference), my_list is copy_list_reference)
# 2400423854016 2400423854016 True
# 修改copy_list_slice中的一个可变元素(子列表)
copy_list_slice = 99
print(my_list) # 输出: [1, 2, 3, [99, 5]],因为浅拷贝,子列表还是引用的同一个对象
print(copy_list_slice) # 输出: [1, 2, 3, [99, 5]]
# 修改copy_list_reference中的一个元素
copy_list_reference = 99
print(my_list) # 输出: [1, 99, 3, [99, 5]],因为它们是同一个列表
print(copy_list_reference) # 输出: [1, 99, 3, [99, 5]]
# 向copy_list_slice添加新元素
copy_list_slice.append(6)
print(my_list) # 输出: [1, 99, 3, [99, 5]],copy_list_slice的修改不影响my_list
print(copy_list_slice) # 输出: [1, 2, 3, [99, 5], 6]
# 向copy_list_reference添加新元素
copy_list_reference.append(7)
print(my_list) # 输出: [1, 99, 3, [99, 5], 7],因为它们是同一个列表
print(copy_list_reference) # 输出: [1, 99, 3, [99, 5], 7]
修改列表
由于列表是可变的,我们可以修改列表中的元素,添加新元素或删除元素。
list1 = [1, 2, 3]
list2 = ['A', 'B', 'C']
# 修改元素
list1[1] = 'a'
print(list1) # 输出: [1, 'a', 3]
# 添加元素
# 在列表末尾添加
list1.append(4)
print(list1) # 输出: [1, 'a', 3, 4]
# 在指定位置插入
list1.insert(1, 'b')
print(list1) # 输出: [1, 'b', 'a', 3, 4]
# 合并列表
list2.extend(list1)
print(list1) # 输出: [1, 'b', 'a', 3, 4]
print(list2) # 输出: ['A', 'B', 'C', 1, 'b', 'a', 3, 4]
print(list2 + list1) # 输出: ['A', 'B', 'C', 1, 'b', 'a', 3, 4]
# 删除元素
# 移除并返回列表的最后一个元素
last_item = list1.pop()
print(last_item) # 输出: 4
print(list1) # 输出: [1, 'b', 'a', 3]
# 删除指定位置的元素
del_item = list1.pop(1) # 删除索引为 1 的元素
print(del_item) # 输出: 'b'
print(list1) # 输出: [1, 'a', 3]
# 直接删除某个值的元素(只删除第一个匹配的元素)
list1.remove('a')
print(list1) # 输出: [1, 3]
# 使用系统语句方式删除某个值的元素
del list1[1]
print(list1) # 输出: [1]
# 删除整个列表的内容,但是保留列表(地址)
list1.clear()
print(list1) # 输出: []
# 使用系统语句方式删除整个列表(包括地址)
del list1
print(list1) # 报错: NameError: name 'list1' is not defined
列表查找
如果你需要知道某个元素在列表中的位置(索引),可以使用
index()
方法。如果元素存在于列表中,index()
方法会返回该元素的第一个匹配项的索引;如果元素不存在,则抛出ValueError
异常。
my_list = ['a', 'b', 'c', 'd']
element = 'c'
try:
index = my_list.index(element)
print(f"{element} 的索引是 {index}")
except ValueError:
print(f"{element} 不存在于列表中")
# 输出: c 的索引是 2
列表的其他用法
- **
list.count(x)
**:
- 返回列表中值为 x 的元素的个数。
- **
list.sort(key=None, reverse=False)
**:
- 对列表进行原地排序。可选参数 key 指定排序的依据(函数),reverse 指定是否倒序排序。
- **
list.reverse()
**:
- 原地反转列表。
- **
list.copy()
**:
- 返回列表的一个浅拷贝。
list.count(x)
:
my_list = [1, 2, 2, 3, 4, 4, 4]
count = my_list.count(4)
print(count) # 输出:3
list.sort(key=None, reverse=False)
:
my_list = [3, 1, 4, 1, 5, 9, 2, 6, 5]
my_list.sort()
print(my_list) # 输出:[1, 1, 2, 3, 4, 5, 5, 6, 9]
# 使用key参数按绝对值排序
my_list = [-3, 1, -4, 1, -5, 9, 2, -6, 5]
my_list.sort(key=abs)
print(my_list) # 输出:[1, 1, 2, -3, -4, 5, -5, -6, 9]
# 使用reverse参数按降序排序
my_list.sort(reverse=True)
print(my_list) # 输出:[9, -5, -6, 5, -3, -4, 2, 1, 1]
list.reverse()
:
my_list = [1, 2, 3, 4, 5]
my_list.reverse()
print(my_list) # 输出:[5, 4, 3, 2, 1]
list.copy()
:
my_list = [1, 2, 3, [4, 5]]
new_list = my_list.copy()
print(new_list) # 输出:[1, 2, 3, [4, 5]]
# 修改嵌套列表中的元素,验证浅拷贝
new_list = 'a'
print(my_list) # 输出:[1, 2, 3, ['a', 5]]
print(new_list) # 输出:[1, 2, 3, ['a', 5]]
列表可使用的符号
- 索引和切片
- 索引:使用方括号
[]
来获取或修改列表中特定位置的元素。- 切片:使用
:
来获取列表的一个子列表。
- 连接(Concatenation)
- 使用加号
+
来连接两个列表。
重复(Repetition)
- 使用星号
*
来重复列表。成员关系
- 使用
in
和not in
检查元素是否在列表中。
内置函数操作列表
内置函数
- **
len(list)
**:
- 返回列表中元素的个数。
- **
max(list)
**:
- 返回列表中的最大值。
- **
min(list)
**:
- 返回列表中的最小值。
- **
sum(list)
**:
- 返回列表中所有元素的和,适用于数字列表。
- **
sorted(list)
**:
- 返回一个新的已排序的列表(不改变原列表)。
- **
list(iterable)
**:
- 将一个可迭代对象(如字符串、元组等)转换为列表。
浅拷贝和深拷贝
在Python中,浅拷贝(shallow copy)和深拷贝(deep copy)是复制对象的两种方式,它们处理对象及其内部元素的方式不同。
浅拷贝(Shallow Copy)
浅拷贝创建一个新的对象,这个新对象与原对象共享内存中的子对象。换句话说,浅拷贝只复制了对象本身和对象中的直接元素,而不复制这些元素所指向的对象。因此,如果原对象中的元素是可变的(如列表、字典等),那么在这些元素上所做的修改会影响到浅拷贝的对象,因为它们共享相同的子对象。
在Python中,可以使用
copy
模块中的copy
函数或者某些内置方法(如列表的.copy()
方法)来实现浅拷贝。深拷贝(Deep Copy)
深拷贝创建一个新的对象,并且递归地复制原对象中的所有对象。这意味着深拷贝不仅复制了对象本身和对象中的直接元素,还复制了这些元素所指向的所有对象,以及这些对象所指向的对象,依此类推,直到达到基本数据类型(如整数、浮点数、字符串等)。因此,深拷贝的对象与原对象是完全独立的,修改其中一个不会影响另一个。
在Python中,可以使用
copy
模块中的deepcopy
函数来实现深拷贝。
import copy
# 创建一个包含嵌套列表的原始列表
original_list = [1, 2, [3, 4]]
# 浅拷贝
shallow_copied_list = copy.copy(original_list)
# 深拷贝
deep_copied_list = copy.deepcopy(original_list)
# 修改原始列表中的嵌套列表
original_list[2][0] = 'a'
# 查看地址
print(id(original_list), id(shallow_copied_list), original_list is shallow_copied_list)
# 输出: 2554351041200 2554354207616 False
print(id(original_list), id(deep_copied_list), original_list is deep_copied_list)
# 输出: 2554351041200 2554354208512 False
# 打印结果
print("Original list:", original_list) # 输出: Original list: [1, 2, ['a', 4]]
print("Shallow copied list:", shallow_copied_list) # 输出: Shallow copied list: [1, 2, ['a', 4]]
print("Deep copied list:", deep_copied_list) # 输出: Deep copied list: [1, 2, [3, 4]]