列表,元组,字符串
笔记
列表
[ 元素1 , 元素2 , … , 元素n ] 。
列表的创建
x = [2, 3, 4, 5, 6, 7]
利用 range() 创建列表
x = list(range(10))
利用推导式创建列表
x = [i for i in range(10)]
x = [0] * 5
创建一个二维数组
x = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [0, 0, 0]]
x = [[0 for col in range(3)] for row in range(4)]
x = [[0] * 3 for row in range(4)]
注意:
由于list的元素可以是任何对象,因此列表中所保存的是对象的指针。即使保存一个简单的 [1,2,3] ,也有3个指针和3个整数对象。
x = [a] * 4 操作中,只是创建4个指向list的引用,所以一旦 a 改变, x 中4个 a 也会随之改变。
x = [[0 for col in range(3)] for row in range(4)]
print(x, type(x))
# [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] <class 'list'>
x[0][0] = 1
print(x, type(x))
# [[1, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] <class 'list'>
x = [[0] * 3 for row in range(4)]
print(x, type(x))
# [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] <class 'list'>
x[1][1] = 1
print(x, type(x))
# [[0, 0, 0], [0, 1, 0], [0, 0, 0], [0, 0, 0]] <class 'list'>
x = [[0] * 3] * 4
print(x, type(x))
# [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] <class 'list'>
x[0][0] = 1
print(x, type(x))
# [[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0]] <class 'list'>
a = [0] * 3
x = [a] * 4
print(x, type(x))
# [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] <class 'list'>
x[0][0] = 1
print(x, type(x))
# [[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0]] <class 'list'>
创建一个混合列表
mix = [1, ‘lsgo’, 3.14, [1, 2, 3]]
创建一个空列表
empty = []
向列表中添加元素
list.append(obj) 在 列表末尾 添加新的对象,只接受一个参数,参数可以是任何数据类型,被追加的元素在 list 中保持着原结构类型
list.extend(seq) 在 列表末尾 一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
注:
添加元素如果是一个 list,那么append里这个 list 将作为一个整体进行追加,extend里直接追加多个值
list.insert(index, obj) 在编号 index 位置 前 插入 obj
删除列表中的元素
list.remove(obj) 移除列表中 某个值 的第一个匹配项
list.pop([index=-1]) 移除列表中的一个 元素(默认最后一个元素),并且返回该元素的值
index索引:从左开始:0,1,2,3……;从右开始:……-2,-1
== del var1[, var2 ……]== 删除单个或多个 对象
注:
如果你要从列表中删除一个元素,且不再以任何方式使用它,就使用 del 语句;如果你要在删除元素后还能继续使用它,就使用方法 pop()
获取列表中的元素
切片的通用写法是 start : stop : step(包含start,不包含stop)
- “start :”
以 step 为 1 (默认) 从编号 start 往列表尾部切片 - “: stop”
以 step 为 1 (默认) 从列表头部往编号 stop 切片 - “start : stop”
以 step 为 1 (默认) 从编号 start 往编号 stop 切片 - “start : stop : step”
以具体的 step 从编号 start 往编号 stop 切片。注意最后把 step 设为 -1,相当于将列表反向排列 - ": "
复制列表中的所有元素(浅拷贝)
补:
浅拷贝和深拷贝
- 直接赋值:
默认浅拷贝对象的引用,原始列表改变,被赋值的b也会做同样的改变 - 浅拷贝:
没有拷贝子对象,所以原始数据改变,子对象会改变
import copy
b=copy.copy(a) - 深拷贝:
包含对象里子对象的拷贝,所以原始对象的改变不会造成深拷贝里任何子元素的改变
单层浅拷贝
import copy
a = 1 # 不可变数据类型
copy_a = copy.copy(a)
print(id(a),id(copy_a)) # 内存地址相同
a = [1,2] # 可变数据类型
copy_a = copy.copy(a)
print(id(a),id(copy_a)) # 内存地址不相同
单层深拷贝
import copy
a = 1 # 不可变数据类型
copy_a = copy.deepcopy(a)
print(id(a),id(copy_a)) # 内存地址相同
a = [1,2] # 可变数据类型
copy_a = copy.deepcopy(a)
print(id(a),id(copy_a)) # 内存地址不相同
结论一:
- 不管深拷贝还是浅拷贝对不可变数据类型都是引用内存地址
- 不管深拷贝还是浅拷贝对可变数据类型都是会重新创建新的内存空间
浅拷贝嵌套
#-----------不可变数据类型---------
#情况一,内嵌可变数据类型
import copy
a = ([1,2],(3,4)) # 不可变数据类型
copy_a = copy.copy(a)
print(id(a),id(copy_a)) # 内存地址相同
#情况二,内嵌不可变数据类型
a = ((1,2),(3,4)) # 不可变数据类型
copy_a = copy.copy(a)
print(id(a),id(copy_a)) # 内存地址相同
#-----------可变数据类型-------------
#情况一,内嵌可变数据类型
import copy
a = [(1,2),[3,4]] # 可变数据类型
copy_a = copy.copy(a)
print(id(a),id(copy_a)) # 内存地址不相同
#情况二,内嵌不可变数据类型
import copy
a = [(1,2),(3,4)]