• 【Python学习】可变类型和不可变类型


    一.可变类型与不可变类型的特点

    1.不可变数据类型

    不可变数据类型在第一次声明赋值声明的时候, 会在内存中开辟一块空间, 用来存放这个变量被赋的值,  而这个变量实际上存储的, 并不是被赋予的这个值, 而是存放这个值所在空间的内存地址, 通过这个地址, 变量就可以在内存中取出数据了. 所谓不可变就是说, 我们不能改变这个数据在内存中的值, 所以当我们改变这个变量的赋值时, 只是在内存中重新开辟了一块空间, 将这一条新的数据存放在这一个新的内存地址里, 而原来的那个变量就不在引用原数据的内存地址而转为引用新数据的内存地址了.

    举例子:

    复制代码
    >>> x = 18
    >>> id(x)
    4497811200
    >>> id(18)
    4497811200
    >>> x = 19 
    >>> id(x)
    4497811232
    >>> id(18)
    4497811200
    >>> y = 18
    >>> id(y)
    4497811200
    >>> 
    复制代码

     一开始x = 18,开辟一块地址为4497811200的内存,即18对应的地址为4497811200,后来x = 19 ,重新开辟一块地址为4497811232的内存来放19,可以看到不变的意思是指18,和19在内存中的地址不会改变,将18赋值给y时,y指向的地址即为4497811200。

    1.可变数据类型

    结合不可变数据类型,可变数据类型就很好理解来,可变数据类型是指变量所指向的内存地址处的值是可以被改变的。

    复制代码
    >>> x = [1,2,3]
    >>> id(x)
    4501838920
    >>> y = [1,2,3]
    >>> z = [1,2,3]
    >>> id(y)
    4501838600
    >>> id(z)
    4501838664
    复制代码

    从另外一个角度来看:

    可变类型:当该数据类型的对应变量的值发生了改变,那么它对应的内存地址也会发生改变,对于这种数据类型,就称不可变数据类型。

    可变数据类型:当该数据类型的对应变量的值发生了改变,那么它对应的内存地址不发生改变,对于这种数据类型,就称可变数据类型。

    复制代码
    #a的值改变了,a对应的内存地址也改变了
    >>> a=1 >>> id(a) 4497810656 >>> a = 2 >>> id(2) 4497810688
    #直接对a操作,相当于拷贝了一份a的值,在其他内存地址操作,a的值不变 >>> a+1 3 >>> id(a) 4497810688 >>> a 2
    #b的值改变了,b对应的内存地址不变,第一次给b赋值的时候,给b划分一块内存空间,该空间就不变了 >>> b = [1,2,3] >>> id(b) 4501839496
    #直接对b操作,b的值改变,b指向的内存空间不变 >>> b.append(4) >>> id(b) 4501839496 >>> b [1, 2, 3, 4] >>>
    复制代码

    二.哪些是可变类型哪些是不可变类型

    不可变:Number(数字)、String(字符串)、Tuple(元组)。

    复制代码
    #整型
    a = 1
    print(id(a), type(a))
    a = 2
    print(id(a), type(a))
    
    # 4361254304 <class 'int'>
    # 4361254336 <class 'int'>
    #字符串
    b = 'anne'
    print(id(b),type(b))
    b = 'anne1995'
    print(id(b),type(b))
    
    # 4363638744 <class 'str'>
    # 4363684784 <class 'str'>
    
    #元组
    c1 = ['1','2']
    c = (1,2,c1)
    print(c,id(c),type(c))
    c1[1] = 'djx'
    print(c,id(c),type(c))
    
    # (1, 2, ['1', '2']) 4363948248 <class 'tuple'>
    # (1, 2, ['1', 'djx']) 4363948248 <class 'tuple'>

    注意:此时元组的值发生了变化而内存地址没变,但我们依然称元组为不可变类型,为什么呢?其实改的是元组中的列表,列表是可变类型,改变了值后地址依然不变。但是元组的定义就是不可变的,

    元组被称为只读列表,即数据可以被查询,但不能被修改。
    复制代码

    可以变:Set(集合)、List(列表)、Dictionary(字典)。

    复制代码
    #集合
    s = {1, 'd', '34', '1', 1}
    print(s, type(s), id(s))
    s.add('djx')
    print(s, type(s), id(s))
    
    # {1, '1', 'd', '34'} <class 'set'> 4401385256
    # {1, '1', '34', 'd', 'djx'} <class 'set'> 4401385256
    
    
    
    #列表
    list = [1,'q','qwer',True]
    print(list,type(list),id(list))
    list.append('djx')
    print(list,type(list),id(list))
    
    # [1, 'q', 'qwer', True] <class 'list'> 4401113608
    # [1, 'q', 'qwer', True, 'djx'] <class 'list'> 4401113608
    
    #字典
    tuple = (1)
    dic = {1:2}
    d = { tuple:1,'key2':'djx','key3':'li'}
    print(d,type(d),id(d))
    d['key4'] = 'haha'
    print(d,type(d),id(d))
    
    # {1: 1, 'key2': 'djx', 'key3': 'li'} <class 'dict'> 4401075976
    # {1: 1, 'key2': 'djx', 'key3': 'li', 'key4': 'haha'} <class 'dict'> 4401075976
    作者:gtea 博客地址:https://www.cnblogs.com/gtea
  • 相关阅读:
    本地缓存方式
    iOS Touch ID 身份认证
    iOS之WKWebView
    [Objective-C]关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
    iOS利用UIDocumentInteractionController和Quick Look打开或预览文档
    轮播图的无限轮播
    贝赛尔曲线UIBezierPath(后续)
    贝赛尔曲线UIBezierPath
    NSRunLoop的进一步理解
    CADisplayLink 及定时器的使用
  • 原文地址:https://www.cnblogs.com/gtea/p/13575703.html
Copyright © 2020-2023  润新知