上篇文章 Python必备基础(三):列表与元组(1)已经讲解了列表的重要性与基础用法,这篇讲解列表深浅拷贝、列表推导式和元组;
额外知识:
当我们给一个变量赋值时,这个变量存的值其实不是值的内容,而是值的存储地址;当我们创造一个值,程序会在内存中开辟一个地址,然后把地址赋值给这个变量,当下次读取次变量时,变量会根据地址去拿到具体的值;
根据对象创建后,是否可以更改其值(也就是内存地址不变,在内存地址对象的空间内,改变值),分为不可变类型和可变类型;
不可变类型:整数(Integer) 和浮点数(Float)
,布尔值(Boolean)
,字符串(String)
,元组(Tuple)
都是不可变类型,意思是次类型的值一旦创建(内存里面的值),如果想要保留地址不变(也就是同一个内存空间),改变内存里面的值,这是不行的,python是不允许的,如果你对一个变量比如a=1,后来改为a=2,你看到的是同一个a,但是a所存的内存地址变了,python会重新开辟一个空间存2,然后把地址给到a,如果1的值有其他变量在用,就不销毁,如果没有,就会被销毁
;
可变类型:列表(List),字典(Dictionary);意思就是列表这个数据类型,可以在保留自己内存地址不变的情况下,改变元素的内容,这是因为列表和字典是复杂的数据类型,存储的方式和基本数据类型不一样;请看下图
列表深浅拷贝
浅拷贝
创建一个新的列表对象,该对象与原始列表共享相同的元素对象。当你对其中一个列表进行修改时,另一个列表也会受到影响。
创建浅拷贝的方法有三个:
- 使用切片操作符[:]进行拷贝
- 使用list()函数进行拷贝
- 使用copy()方法进行拷贝(需要导入copy模块)
# (1)使用切片操作符[:]进行拷贝:
l1 = [1, 2, 3, 4, 5]
l = l1[:]
# (2)使用list()函数进行拷贝
l2 = [1, 2, 3, 4, 5]
l = list(l2)
# (3)使用copy()方法进行拷贝(需要导入copy模块)
l3 = [1, 2, 3, 4, 5]
l = l3.copy()
stars = ["杨紫","赵丽颖","白鹿",["敖瑞鹏","胡歌"]]
# 浅拷贝stars
stars2 = stars.copy()
# 打印 stars2
print("浅拷贝的stars2",stars2)
# 修改stars2的第一个成员,这个成员是基本数据类型
stars2[0] = "super Zhao"
print("修改过的第一个基本元素的stars2",stars2) #['杨紫', '赵丽颖', '白鹿', ['敖瑞鹏', '胡歌']]
print("原stars",stars) # ['super Zhao', '赵丽颖', '白鹿', ['敖瑞鹏', '胡歌']]
stars2[-1][0] = "修改过的敖瑞鹏"
print("修改过的列表类型的元素的stars2",stars2) # ['super Zhao', '赵丽颖', '白鹿', ['修改过的敖瑞鹏', '胡歌']]
print("原stars",stars) # ['杨紫', '赵丽颖', '白鹿', ['修改过的敖瑞鹏', '胡歌']]
通过上图两个图知道,对一个对象浅拷贝后,修改两个中的任何一个列表里面的基本类型元素,是相互不影响的,因为基本元素类型是不可变的,改变了其值,会在内存中生成一个新的值,这个新值的内存地址会更新到原元素的位置上面;所以两个对象的基本元素的修改是相互不影响的
;
修改列表里面的列表元素的值,是相互影响的,因为虽然列表元素里面的值变量,但是第一层列表对象所存储的列表元素的内存地址是不变的,所以两个列表对象会相互影响
;
如果想要不受影响,可以使用深拷贝;
深拷贝
创建一个新的列表对象,并且递归地复制原始列表中的所有元素对象。这意味着原始列表和深拷贝的列表是完全独立的,对其中一个列表的修改不会影响另一个列表。
可以使用copy()模块中的deepcopy()函数进行深拷贝
import copy
stars = ["杨紫","赵丽颖","白鹿",["敖瑞鹏","胡歌"]]
# 浅拷贝stars
stars2 = copy.deepcopy(stars)
# 打印 stars2
print("深拷贝的stars2",stars2)
stars2[-1][0] = "修改过的敖瑞鹏"
print("修改过的列表类型的元素的stars2",stars2) # ['super Zhao', '赵丽颖', '白鹿', ['修改过的敖瑞鹏', '胡歌']]
print("原stars",stars) # ['杨紫', '赵丽颖', '白鹿', ['修改过的敖瑞鹏', '胡歌']]
需要注意的是,深拷贝可能会更耗费内存和时间,特别是当拷贝的列表中包含大量嵌套的对象时。
列表推导式
列表推导式(List comprehensions)是一种简洁的语法,用于创建新的列表,并可以在创建过程中对元素进行转换、筛选或组合操作。
列表推导式的一般形式为:
new_list = [expression for item in iterable if condition]
其中:
expression
是要应用于每个元素的表达式或操作。item
是来自可迭代对象(如列表、元组或字符串)的每个元素。iterable
是可迭代对象,提供要遍历的元素。condition
是一个可选的条件,用于筛选出满足条件的元素。
# 创建一个包含1到5的平方的列表
squares = [x**2 for x in range(1, 6)]
print(squares) # 输出: [1, 4, 9, 16, 25]
# 筛选出长度大于等于5的字符串
words = ["apple", "banana", "cherry", "date", "elderberry"]
filtered_words = [word for word in words if len(word) >= 5]
print(filtered_words) # 输出: ["apple", "banana", "cherry"]
# 将两个列表中的元素进行组合
numbers = [1, 2, 3]
letters = ['A', 'B', 'C']
combined = [(number, letter) for number in numbers for letter in letters]
print(combined) # 输出: [(1, 'A'), (1, 'B'), (1, 'C'), (2, 'A'), (2, 'B'), (2, 'C'), (3, 'A'), (3, 'B'), (3, 'C')]
元组
元组(Tuple)是Python中的一种数据类型,它是一个有序的、不可变的序列。元组使用圆括号 () 来表示,其中的元素可以是任意类型,并且可以包含重复的元素。
与列表(List)不同,元组是不可变的,这意味着一旦创建,它的元素就不能被修改、删除或添加。元组适合用于存储一组不可变的数据。例如,你可以使用元组来表示一个坐标点的 x 和 y 坐标值,或者表示日期的年、月、日等。元组也被称为只读列表
info = ("yuan", 20, 90)
# 获取长度
print(len(info))
# 索引和切片
print(info[2])
print(info[:2])
# 成员判断
print("yuan" in info)
# 拼接
print((1, 2) + (3, 4))
# 循环
for i in info:
print(i)
# 内置方法
print(t.index(5))
print(t.count(2))