Day 3:list 和 tuple 的基本操作、深浅拷贝和切片操作

列表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后,你看:

 

posted @ 2020-09-24 19:48  PiaYie  阅读(273)  评论(0编辑  收藏  举报