列表List
列表(list)是一个可增加、删除元素的可变(mutable)容器。
创建方式:用一对中括号即可;
empty = [] lst = [1,'xiaoming',29.5,'17312662388'] lst2 = ['001','2019-11-11',['三文鱼','电烤箱']]
我们可以使用 Python 的内置函数 len 求 list 内元素个数.
依次遍历 lst 内每个元素并求对应类型,使用 for in
对遍历,内置函数 type 得到类型:
>>> lst = [1,'xiaoming',29.5,'17312662388'] >>> for _ in lst: ... print(f'{_}的类型为{type(_)}') ... 1的类型为<class 'int'> xiaoming的类型为<class 'str'> 29.5的类型为<class 'float'> 17312662388的类型为<class 'str'>
有趣的是,python3.6更新了一种格式化输出:print()内以 f 开头,包含的{}表达式在程序运行时会被表达式的值代替
显然。python中的list不要求元素类型一致,甚至可以包含其他列表
现在问题来了,我们需要索引操作,访问到列表中的元素或者是列表中的列表中的元素。
>>> lst2 = ['001','2019-11-11',['三文鱼','电烤箱']] >>> sku = lst2[2]#浅拷贝,传递对象的引用 you jump i jump >>> sku.append('烤鸭')#用列表的 append 方法增加元素,append 默认增加到 sku列表尾部 >>> print(sku) ['三文鱼', '电烤箱', '烤鸭'] >>> sku.insert(1,'牛腱子')#使用列表的 insert 方法,在 sku 指定索引 1 处插入“牛腱子” >>> print(sku) ['三文鱼', '牛腱子', '电烤箱', '烤鸭'] >>> item = sku.pop()#使用 pop 方法可直接移除列表尾部元素,这里是先做pop()再用pop函数返回值进行赋值操 作 >>> print(sku) ['三文鱼', '牛腱子', '电烤箱'] >>> sku.remove('三文鱼')#列表有 remove 方法,来移除某一个确定的元素 >>> print(sku) ['牛腱子', '电烤箱']
深浅拷贝
1、在电脑id存储方面,当用等号给一个变量重新赋值以后,那个前后两个变量的电脑id存储地址是一样的
但是深浅拷贝后,即使变量下的内容完全一样,但是在电脑中存储的地址是不一样的。
2、原始变量列表中,列表中套列表,最里层列中的元素叫子对象,外边的叫父对象。
3、如果给原始变量列表(最外层)添加一个元素,不管是深拷贝还是浅拷贝,都不会跟随添加新的元素
4、如果给最里层列表中添加子对象元素,深拷贝仍然不会跟随添加新的元素,但是浅拷贝会跟随添加
5、如果原始变量列表中更改一个子元素,深浅拷贝后不会跟着改变
就是说,深拷贝是比较完全拷贝的拷贝,更加自主,浅拷贝就比较被动了
>>> a = [1, 2, 3, 4, [3, 4, 5]] >>> b = a >>> import copy >>> c = copy.deepcopy(a) >>> d = copy.copy(a) >>> print(id(a)) 2246786514560 >>> print(id(b)) 2246786514560 >>> print(id(c)) 2246786583360 >>> print(id(d)) 2246787154752 >>> a.append('666666') >>> print(a) [1, 2, 3, 4, [3, 4, 5], '666666'] >>> print(b) [1, 2, 3, 4, [3, 4, 5], '666666'] >>> print(c) [1, 2, 3, 4, [3, 4, 5]] >>> print(d) [1, 2, 3, 4, [3, 4, 5]] >>> a[4].append('777777777777777777') >>> print(a) [1, 2, 3, 4, [3, 4, 5, '777777777777777777'], '666666'] >>> print(b) [1, 2, 3, 4, [3, 4, 5, '777777777777777777'], '666666'] >>> print(c) [1, 2, 3, 4, [3, 4, 5]] >>> print(d) [1, 2, 3, 4, [3, 4, 5, '777777777777777777']] >>> a[3] = '444444444' >>> print(a) [1, 2, 3, '444444444', [3, 4, 5, '777777777777777777'], '666666'] >>> print(b) [1, 2, 3, '444444444', [3, 4, 5, '777777777777777777'], '666666'] >>> print(c) [1, 2, 3, 4, [3, 4, 5]] >>> print(d) [1, 2, 3, 4, [3, 4, 5, '777777777777777777']] >>> a.pop() '666666' >>> print(a) [1, 2, 3, '444444444', [3, 4, 5, '777777777777777777']] >>> print(b) [1, 2, 3, '444444444', [3, 4, 5, '777777777777777777']] >>> print(c) [1, 2, 3, 4, [3, 4, 5]] >>> print(d) [1, 2, 3, 4, [3, 4, 5, '777777777777777777']] >>>
切片
Java 和 C++ 中,访问数组中的元素只能一次一个,但 Python 增加切片功能为访问列表带来极大便利。
利用内置函数 range(start,stop[,step]) 生成序列数据,并转为 list 类型:
>>> a = list(range(1,20,3)) >>> a [1, 4, 7, 10, 13, 16, 19]
使用 a[:3] 获取列表 a 的前三个元素,形象称这类操作为“切片”,切片本身也是一个列表 [1,4,7]:
- 使用 a[-1] 获取 a 的最后一个元素,返回 int 型,值为 19;
- 使用 a[:-1] 获取除最后一个元素的切片 [1, 4, 7, 10, 13, 16];
- 使用 a[1:5] 生成索引为 [1,5)(不包括索引 5)的切片 [4, 7, 10, 13];
- 使用 a[1:5:2] 生成索引 [1,5) 但步长为 2 的切片 [4,10];
- 使用 a[::3] 生成索引 [0,len(a)) 步长为 3 的切片 [1,10,19];
- 使用 a[::-3] 生成逆向索引 [len(a),0) 步长为 3 的切片 [19,10,1]。
我们有时候会想要直接逆向输出一个list, 聪明的你已经想得到在C中怎么做了:新建一个原list长的数组指针,然后用for循环一一赋值?行吧,假设可行,怎么说也得好几行代码,而PYTHON中不要,only one: lst[::-1]
>>> def reverse(lst): ... return lst[::-1] ... >>> ra = reverse(a) >>> ra [19, 16, 13, 10, 7, 4, 1] >>>
元组
接下来说一说元组中的操作,元,意味着不可变(immutable),没有增加、删除、修改这样的操作,
那要他何用?
使用一对括号()就能创建一个元组对象:
a = () # 空元组对象 b = (1,'xiaoming',29.5,'17312662388') c = ('001','2019-11-11',['三文鱼','电烤箱'])
注意,看起来和list没啥不同,而且tuple也支持切片操作,
不过有一点值得注意,一个整数加一对括号,比如 (10),返回的是整数。必须加一个逗号 (10, ) 才会返回元组对象。
>>> c = ('001','2019-11-11',['三文鱼','电烤箱']) >>> c[::-1] (['三文鱼', '电烤箱'], '2019-11-11', '001') >>> d = ([1, 2, 3]) >>> e = ([1, 2, 3], ) >>> type(d) <class 'list'> >>> type(e) <class 'tuple'> >>>
列表和元组都有一个很好用的统计方法 count,实现对某个元素的个数统计:
>>> a = [1, 222, 231, [(45,'asas',), 33]] >>> b = (211, 2121 , '2121',) >>> a.count(1) 1 >>> a.append(1) >>> a.count(1) 2 >>> b.count(1) 0 >>> b.count(2121) 1 >>>
可变对象与不可变对象
元组和列表都是容器,我们常说,列表是可变容器,元组是不可变容器:
列表可以增加或者删除(可变):
>>> a = [1,3,[5,7],9,11,13] >>> a.pop() 13 >>> a [1, 3, [5, 7], 9, 11] >>> a.insert(3, 8) >>> a [1, 3, [5, 7], 8, 9, 11] >>>
>>> a[2].insert(1,66)
>>> a
[1, 3, [5, 66, 7], 8, 9, 11]
>>>
tuple 就是一个典型的不可变容器对象。对它而言,同样也可以修改嵌套对象的取值,但这并没有真正改变 tuple 内的元素。
不可变对象的本质,元组一旦创建后,长度就被唯一确定
a =(1,3,[5,7],9,11,13)
>>> a =(1,3,[5,7],9,11,13) >>> a.pop() Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'tuple' object has no attribute 'pop' >>> a[2].insert(1,66) >>> a (1, 3, [5, 66, 7], 9, 11, 13) >>>
insert后,你看: