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

  • 相关阅读:
    Gym 102040B Counting Inversion(超级数位dp)
    Educational Codeforces Round 104 (Rated for Div. 2)(A~D)
    2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1)_组队训练
    线段树板子
    Codeforces Round #700 (Div. 2)
    Codeforces Round #699 (Div. 2)
    Codeforces Round #698 (Div. 2)
    字典树——实现字符串前缀查找(可返回字符串)
    LeetCode146-LRU缓存机制
    用到过的git命令
  • 原文地址:https://www.cnblogs.com/PiaYie/p/13722263.html
Copyright © 2020-2023  润新知