python的列表、元组、深拷贝、浅拷贝(四)

python的列表

  • 一、序列
  • 1. 序列定义
  • 2. 序列数据类型包括
  • 3.特点:都支持下面的特性
  • 二、 列表
  • 1. 列表的创建
  • 2. 列表的基本特性
  • (1) 连接操作符喝重复操作符
  • (2) 成员操作符(in , not in )
  • (3) 索引
  • (4) 切片
  • 练习
  • (5) for循环
  • 3. 列表的常用方法
  • (1) 一次添加一个元素
  • (2) 增加列表的内容
  • (3) 修改列表内容:通过索引和切片重新赋值的方式
  • (4) 查看:通过索引和切片查看元素
  • (5) 删除列表中某元素
  • 4. 列表的翻转,排序,拷贝功能
  • 三、元组tuple的操作(戴了紧箍咒的列表,不能修改元素)
  • 1. 元组的创建
  • 2. 元组的特性
  • 3. 常用方法
  • 四、 命名元组的使用
  • 练习
  • 五、地址引用和深拷贝和潜拷贝
  • 1. 数据类型分类
  • 2. 值得引用
  • 3. 潜拷贝
  • 4. 深拷贝
  • 如果列表的元素包含可变数据类型(可增删改:list) ,一定要用深拷贝!!!!
  • 5. 浅拷贝与深拷贝的区别
  • 6. 结论
  • 一、序列

    1. 序列定义

  • 成员有序排列的,且可以通过下标偏移量访问到它的一个或者几个成员,这类类型统称为序列
  • 2. 序列数据类型包括

  • 字符串,列表,元组
  • 3.特点:都支持下面的特性

  • 索引和切片操作符
  • 成员关系操作符(in,not in)
  • 连接操作符(+)和重复操作符(*)
  • 二、 列表

    1. 列表的创建

    li = []
    print(li, type(li))
    

    2. 列表的基本特性

    (1) 连接操作符喝重复操作符
    print([1,2] + [2,3])     #输出[1, 2, 2, 4]
    print([1,2] * 3)         #输出[1, 2, 1, 2, 1, 2]
    
    (2) 成员操作符(in , not in )
    print(1 in [1,2,3])                #输出True
    print(1 in ["a", True, [1,2]])     #输出True. 原因:在布尔类型里面,True为1,False为0,此处将1=True
    print("z" in ["a", True, [1,2,"z"]])  #输出False
    

    split’,'[172,25,254,100]

    (3) 索引
    li = [1,2,3,[1,"b",3]]
    print(li[0])  #输出1
    print(li[-1])  #输出[1,"b",3]
    print(li[-1][0])  #输出1
    print(li[3][-1])  #输出3
    
    (4) 切片
    li =['172','25','254','100']
    print(li[:3])   #['172', '25', '254']
    print(li[1:])   #['25', '254', '100']
    print(li[::-1]) #倒着输出['100', '254', '25', '172']
    
    练习
    # 需求:已知列表list =['172','25','254','100'],请输出“100-254-25”
    print('-'.join(li[-3:0:-1]))
    print('-'.join(li[:0:-1]))
    print('-'.join((li[1:][::-1])))  
    
    (5) for循环
    names = ["粉丝", "粉条", "粉带"]
    for name in names:
        print(f"猫猫叫:{name}" )    
    

    3. 列表的常用方法

    (1) 一次添加一个元素
    li = [1, 2, 3]
    li.append(4)
    print(li)
    输出结果:  [1, 2, 3, 4]
    
    (2) 增加列表的内容
    1. 一次追加多个元素
    li = [1, 2, 3]
    li.append([4,5,6])
    print(li)
    
    输出结果:  [1, 2, 3, [4, 5, 6]]
    
    list1 = [1, 2, 3]
    list1.extend([4,5,6])
    print(list1)
    
    输出结果: [1, 2, 3, 4, 5, 6]
    
    1. 在列表开头添加
    list2 = [1, 2, 3]
    list2.insert(0,"cat")
    print(list2)
    
    输出结果: ['cat', 1, 2, 3]
    
    1. 在指定索引前面加dog
    list3 = [1, 2, 3]
    list3.insert(2,"dog")
    print(list3)
    
    输出结果: [1, 2, 'dog', 3]
    
    (3) 修改列表内容:通过索引和切片重新赋值的方式
    list = [1, 2, 3]
    list[0] = "cat"  #通过索引的方式修改
    list[-1] = "dog"
    print(list)
    
    list[:2] = ["pink","black"]  #通过切片的方式修改
    print(list)
    
    输出结果:
    ['cat', 2, 'dog']
    ['pink', 'black', 'dog']
    
    
    (4) 查看:通过索引和切片查看元素

    原理:查看索引值和出现的次数

    li =[1,2,3,1,1,2,3]
    print(li.count(1))   #计算1出现了几次
    print(li.index(2))   #查找2第一次出现时的索引值
    
    (5) 删除列表中某元素
    1. 根据索引删除
    li = [1,2,3]
    delete_num = li.pop(1)   #若不写索引值,默认为最后一个
    print("删除的元素是:",delete_num)  # 删除的元素是: 2
    print(li)  #[1, 3]
    
    1. 根据valuse值删除
    li = [1,2,3]
    li.remove(1)
    print(li)  #[2, 3]
    
    1. 全部清空
    li = [1,2,3]
    li.clear()
    print(li) #输出 []
    

    4. 列表的翻转,排序,拷贝功能

    
    li = [18,6,56,32]
    li.reverse()  #类似于 [::-1],具有反转的功能
    print(li)  #[32, 56, 6, 18]
    
    
    #sort排序默认由小到大,如果想由大到小排序,需设置reverse=true
    li.sort(reverse=True)  #按照由大到小排列
    print(li)  #[6, 18, 32, 56]
    
    #拷贝
    li1 = li.copy()
    print(id(li),id(li1)) #打印内存信息
    print(li,li1)
    
    

    三、元组tuple的操作(戴了紧箍咒的列表,不能修改元素)

    1. 元组的创建

    >>> t1 =()  #空元组
    >>> print(t1,type(t1))
    () <class 'tuple'>
    
    >>> t1 =(1)
    >>> print(t1,type(t1)) # 只有单个元素不是元组
    1 <class 'int'>
    
    >>> t1 =(1,)
    >>> print(t1,type(t1)) #元组只有一个元素的时候一定要加逗号
    (1,) <class 'tuple'>
    
    >>> t1 =(1,1.2,True,[1,1,3])
    >>> print(t1,type(t1))
    (1, 1.2, True, [1, 1, 3]) <class 'tuple'>
    

    2. 元组的特性

    拼接

    >>> print((1,2,3)+(1,))
    (1, 2, 3, 1)
    >>> print((1,2,3)*5)
    (1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3)
    >>> print(1 in (1,2,3))
    True
    >>> t = (1,2,3,4)
    >>> print(t[0])
    1
    >>> print(t[-1])
    4
    >>> print(t[::-1])
    (4, 3, 2, 1)
    >>> print(t[:2])
    (1, 2)
    >>> print(t[1:])
    (2, 3, 4)
    >>>
    

    3. 常用方法

    元组是不可变数据类型,不能增删改,只能查看

    # 通过索引和切片查看元素
    >>> t=(1,2,3,1,1,3)
    >>> print(t.count(3))
    2
    >>> print(t.index(3))
    2
    

    四、 命名元组的使用

    # 从collections模块导入namedtuple工具
    from collections import namedtuple
    #创建命名元组User
    User = namedtuple('User', ("name", "age", "city"))
    #给命名元组传值
    user1 = User("westos", 18, "西安")
    #打印命名元组
    print(user1)
    #获取命名元组指定的信息
    print(user1.name)
    print(user1.age)
    print(user1.age)
    
    练习
    from collections import namedtuple
    menu = """
                云主机管理系统
            1). 添加云主机(IP,hostname,IDC)
            2). 搜索云主机(IP搜索)
            3). 删除云主机
            4). 云主机列表
            5). 退出系统
    请输入你的选择:"""
    
    hosts = []
    Host =namedtuple('Host', ('ip', 'hostname', 'idc'))
    while True:
        choice = input(menu)
        if choice == "1":
            print("添加云主机".center(50, '*'))
            ip = input("请输入IP地址:")
            hostname = input("请输入正确的主机名:")
            idc = input("请输入idc(eg:ali,huawei...)名称:")
            Host1 = Host(ip, hostname, idc)
            hosts.append(Host1)
            print(f"添加{idc}的云主机成功,IP地址为{ip}")
        elif choice == "2":
            print("搜索云主机".center(50, '*'))
            ip = input("请输入需要搜索的主机IP:")
            for host in hosts:
                if ip == host.ip:
                    print(f"{host.ip}\t{host.hostname}\t{host.idc}")
                    break
            else:
                print("请输入正确的IP地址")
        elif choice == '3':
            print("删除云主机".center(50, "*"))
            ip = input("请输入需要删除的主机IP:")
            for host in hosts:
                if ip == host.ip:
                    hosts.remove(host)
        elif choice == "4":
            print("云主机列表".center(50, '*'))
            count =0
            print("IP\t\t\thostname\t\tidc")
            for host in hosts:
                count += 1
                print(f'{host.ip}\t\t{host.hostname}\t\t\t{host.idc}')
            print("主机总个数为:", count)
        elif choice == '5':
            print("系统正在退出,欢迎下次使用....")
            exit()
        else:
            print("请输入正确的选项")
    

    五、地址引用和深拷贝和潜拷贝

    1. 数据类型分类

  • 不可变数据类型: 数值,字符串str,tuple,nametuple
  • 可变数据类型(可增删改) :list
  • 2. 值得引用

  • nums1和nums2指向同一个内存空间(=)
  • nums1 = [1, 2, 3]
    nums2 = nums1
    nums1.append(4)
    print(nums2)  #结果输出为[1, 2, 3, 4]
    

    3. 潜拷贝

  • 对内存地址的拷贝,n1 n2指向同一个内存地址,修改n1会影响n2(li.copy(),copy.copy)
  • n1 = [1, 2, 3]
    n2 =n1.copy() #n1.copy()和n1[:]都可以实现拷贝
    print(id(n1), id(n2))  #1879038751488 1879038753920
    n1.append(4)
    print(n2)  #[1, 2, 3]
    
    潜拷贝:
    
    n1 = [1, 2, [1, 2]]
    n2 = n1.copy()
    n1[-1].append(4)
    print(n2)
    print(id(n1), id(n2))
    print(id(n1[-1]), id(n2[-1]))
    
    输出结果:
    [1, 2, [1, 2, 4]]
    2981595640768 2981595640576
    2981595640704 2981595640704
    
    

    4. 深拷贝

    如果列表的元素包含可变数据类型(可增删改:list) ,一定要用深拷贝!!!!
  • 拷贝另外一个变量的值,n1 n2的内存地址不同,修改n1并不会影响n2(copy.deepcopy())
  • import copy
    n1 = [1, 2, [1, 2]]
    n2 = copy.deepcopy(n1)
    n1[-1].append(4)
    print(id(n1), id(n2))
    print(id(n1[-1]), id(n2[-1]))
    print(n2)
    输出:2350387450944 2350388443776
    2350387805824 2350388443136
    [1, 2, [1, 2]]
    

    5. 浅拷贝与深拷贝的区别

    最根本的区别在于是否真正获取一个对象的复制实体,而不是引用
    假设B复制了A,修改A的时候,看B是否发生变化:
    如果B跟着变了,说明是潜拷贝,拿人手短(修改堆内存中的同一个值)
    如果B没有改变,说明是深拷贝,自食其力(修改堆内存中的不同的值)

    6. 结论

    作者:酒米_linyx

    物联沃分享整理
    物联沃-IOTWORD物联网 » python的列表、元组、深拷贝、浅拷贝(四)

    发表回复