• day6__基础(is,代码块,缓存机制,集合,深浅copy)


    一、is 判断的是内存地址是否相同

    ​ 在Python中,id是什么?id是内存地址,那就有人问了,什么是内存地址呢? 你只要创建一个数据(对象)那么都会在内存中开辟一个空间,将这个数据临时加在到内存中,那么这个空间是有一个唯一标识的,就好比是身份证号,标识这个空间的叫做内存地址,也就是这个数据(对象)的id,那么你可以利用id()去获取这个数据的内存地址

    l1 = [1,2,3]
    l2 = [1,2,3]
    print(id(l1),id(l2))
    print(l1 is l2)
    输出结果如下:
    2421600222080 2421601939264
    False
    
    s1 = 'mrxiong'
    s2 = 'mrxiong'
    print(id(s1),id(s2))
    print(s1 is s2)
    输出结果如下:
    2421601938672 2421601938672
    True    
    

    那么 is 是什么? == 又是什么?

    ​ ==是比较的两边的数值是否相等,而 is 是比较的两边的内存地址是否相等。 如果内存地址相等,那么这两边其实是指向同一个内存地址。

    • id相同,值一定相同
    • 值相同,id不一定相同

    二、代码块

    1、代码块
    • 代码块:我们所有的代码都需要依赖代码块执行

    • 一个文件就是一个代码块

    • 交互式命令下一行就是一个代码块

    2、两个机制
    • 同一个代码块下,有一个机制

    • 不同的代码块下,遵循另一个机制

    3、同一个代码块下的缓存机制

    ​ Python在执行同一个代码块的初始化对象的命令时,会检查是否其值是否已经存在,如果存在,会将其重用。换句话说:执行同一个代码块时,遇到初始化对象的命令时,他会将初始化的这个变量与值存储在一个字典中,在遇到新的变量时,会先在字典中查询记录,如果有同样的记录那么它会重复使用这个字典中的之前的这个值。所以在你给出的例子中,文件执行时(同一个代码块)会把i1、i2两个变量指向同一个对象,满足缓存机制则他们在内存中只存在一个,即:id相同。

    l1 = 10000
    l2 = 10000
    l3 = 10000
    print(id(l1),id(l2),id(l3))
    输出结果:3045461481424 3045461481424 3045461481424
    
    • 前题条件:同一代码块
    • 优点:节省内存、提升性能。
    • 适用对现: int、 bool、str
    • 具体细则:所有的数字,bool值,机乎所有的字符串
    4、不同代码块下的缓存机制:小数据池

    ​ Python自动将-5~256的整数进行了缓存,当你将这些整数赋值给变量时,并不会重新创建对象,而是使用已经创建好的缓存对象。

    ​ python会将一定规则的字符串在字符串驻留池中,创建一份,当你将这些字符串赋值给变量时,并不会重新创建对象, 而是使用在字符串驻留池中创建好的对象。

      其实,无论是缓存还是字符串驻留池,都是python做的一个优化,就是将~5-256的整数,和一定规则的字符串,放在一个‘池’(容器,或者字典)中,无论程序中那些变量指向这些范围内的整数或者字符串,那么他直接在这个‘池’中引用,言外之意,就是内存中之创建一个。

    • 前提条件:不同代码块
    • 适用对现: int、 bool、str
    • 具体细则:-5----256数字、bool、满 足规则的字符串
    • 优点:节省内存、提升性能。

    三、集合

    ​ python基础数据类型之:集合set。容器型的数据类型,它要求它里面的元素是不可变的数据。但是它本身是可变的数据类型,集合是无序的。{}

    • 集合的作用:
      • 列表的去重
      • 关系测试:交集、并集、差集
    1、集合的创建
    set1 = {1,3,'mrxing',4,'小米',False,'天气'}
    print(set1)
    输出结果:
    {False, 1, 3, 4, '天气', 'mrxing', '小米'}
    

    由此例子看到,集合是无序的

    2、空集合
    set2 = set()
    print(set2)
    
    3、集合的增

    add

    set1 = {1,3,'mrxing',4,'小米','三胖','天气'}
    set1.add('xxxx')
    print(set1)
    

    update迭代着增加

    set1.update('A')
    print(set1)
    set1.update('老师')
    print(set1)
    set1.update([1,2,3])
    print(set1)
    
    4、集合的删
    set1 = {'alex', 'wusir', 'ritian', 'egon', 'barry'}
    
    set1.remove('alex')  # 删除一个元素
    print(set1)
    
    set1.pop()  # 随机删除一个元素
    print(set1)
    
    set1.clear()  # 清空集合
    print(set1)
    
    del set1  # 删除集合
    print(set1)
    
    5、变相改值
    set1 = {'alex', 'wusir', 'ritian', 'egon', 'barry'}
    set1.add('男神')
    set1.remove('alex')
    print(set1)
    
    6、集合的其他操作
    6.1 交集。(& 或者 intersection)
    set1 = {1,2,3,4,5}
    set2 = {4,5,6,7,8}
    print(set1 & set2)  # {4, 5}
    print(set1.intersection(set2))  # {4, 5}
    
    6.2 并集。(| 或者 union)
    set1 = {1,2,3,4,5}
    set2 = {4,5,6,7,8}
    print(set1 | set2)  # {1, 2, 3, 4, 5, 6, 7,8}
    
    print(set2.union(set1))  # {1, 2, 3, 4, 5, 6, 7,8}
    
    6.3 差集。(- 或者 difference)
    set1 = {1,2,3,4,5}
    set2 = {4,5,6,7,8}
    print(set1 - set2)  # {1, 2, 3}
    print(set1.difference(set2))  # {1, 2, 3}
    
    6.4 反交集。 (^ 或者 symmetric_difference)
    set1 = {1,2,3,4,5}
    set2 = {4,5,6,7,8}
    print(set1 ^ set2)  # {1, 2, 3, 6, 7, 8}
    print(set1.symmetric_difference(set2))  # {1, 2, 3, 6, 7, 8}
    
    6.5子集与超集
    set1 = {1,2,3}
    set2 = {1,2,3,4,5,6}
    
    print(set1 < set2)
    print(set1.issubset(set2))  # 这两个相同,都是说明set1是set2子集。
    
    print(set2 > set1)
    print(set2.issuperset(set1))  # 这两个相同,都是说明set2是set1超集。
    
    6.6 frozenset不可变集合,让集合变成不可变类型。
    s = frozenset('barry')
    print(s,type(s))  # frozenset({'a', 'y', 'b', 'r'}) <class 'frozenset'>
    
    7、列表去重
    li = [1,2,1,2,3,4,5,6,5,10,1]
    set1 = set(li)
    li = list(set1)
    print(li)   #[1, 2, 3, 4, 5, 6, 10]
    

    列表去重,不能保留原来列表的顺序

    li = [1,'mrxiong',2,1,2,'mrxiong',3,4,5,6,'mrxiong',5,10,1]
    set1 = set(li)
    li = list(set1)
    print(li)  #[1, 2, 3, 'mrxiong', 4, 5, 6, 10]
    

    四、其它

    for循环:用户按照顺序循环可迭代对象的内容。

    msg = '认证咨询服务机构_全国十大认证机构'
    for item in msg:
        print(item)
    
    li = ['alex','银角','女神','egon','太白']
    for i in li:
        print(i)
    
    dic = {'name':'太白','age':18,'sex':'man'}
    for k,v in dic.items():
        print(k,v)
    

    五、深浅copy

    1、先看赋值运算。
    l1 = [1,2,3,['barry','alex']]
    l2 = l1
    
    l1[0] = 111
    print(l1)  # [111, 2, 3, ['barry', 'alex']]
    print(l2)  # [111, 2, 3, ['barry', 'alex']]
    
    l1[3][0] = 'wusir'
    print(l1)  # [111, 2, 3, ['wusir', 'alex']]
    print(l2)  # [111, 2, 3, ['wusir', 'alex']]
    

    ​ 对于赋值运算来说,l1与l2指向的是同一个内存地址,所以他们是完全一样的,在举个例子,比如张三李四合租在一起,那么对于客厅来说,他们是公用的,张三可以用,李四也可以用,但是突然有一天张三把客厅的的电视换成投影了,那么李四使用客厅时,想看电视没有了,而是投影了,对吧?l1,l2指向的是同一个列表,任何一个变量对列表进行改变,剩下那个变量在使用列表之后,这个列表就是发生改变之后的列表。

    2、浅copy
    l1=[1,2,3,[22,33]]
    l2 = l1.copy()
    l1.append(666)
    print(l1,id(l1))
    print(l2,id(l2))
    输出结果:
    [1, 2, 3, [22, 33], 666] 3011484790656
    [1, 2, 3, [22, 33]] 3011484790400
    
    l1=[1,2,3,[22,33]]
    l2 = l1.copy()
    l1[-1].append(666)
    print(l1,id(l1))
    print(l2,id(l2))
    输出结果:
    [1, 2, 3, [22, 33, 666]] 2821469319040
    [1, 2, 3, [22, 33, 666]] 2821469318784    
    

    ​ 对于浅copy来说,只是在内存中重新创建了开辟了一个空间存放一个新列表,但是新列表中的元素与原列表中的元素是公用的。

    img

    3、深拷贝deepcopy
    import copy
    l1=[1,2,3,[22,33]]
    l2=copy.deepcopy(l1)
    print(id(l1))
    print(id(l2))
    l1[-1].append(666)
    l1.append(777)
    print(l1)
    print(l2)
    输出结果:
    2353320427712
    2353322012352
    [1, 2, 3, [22, 33, 666], 777]
    [1, 2, 3, [22, 33]]
    

    img

    ​ 对于深copy来说,列表是在内存中重新创建的,列表中可变的数据类型是重新创建的,列表中的不可变的数据类型是公用的。

    l1 = [1, 2, 3, 4, ['alex']]
    l2 = l1[::]
    print(l2)
    l1[-1].append(666)
    print(l1)
    print(l2)
    

    浅copy:list dict:嵌套的可变的数据类型是同一个

    深copy:list dict:嵌套的可变的数据类型 不是同一个

    六、练习

    1、请用代码验证name是否是在字典的键中?

    info = {'name':'张三','hobby':'铁狂','age':18}

    info = {'name':'张三','hobby':'铁狂','age':18}
    print('name' in info.keys())
    

    2、请用代码验证张三是否是在字典的键值中?

    info = {'name':'张三','hobby':'铁狂','age':18}

    info = {'name':'张三','hobby':'铁狂','age':18}
    print('张三' in info.values())
    

    3、循环提示用户输入,并将输入内容追加到列表中(如果输入N或者n则停止循环)

    l1 = [1, 2, 3, 4, '李四']
    while 1:
        a = input('请输入需要追加到列表的内容,如果退出输入n:')
        if a.upper() == 'N':
            print('程序结束~!')
            break
        else:
            l1.append(a)
        print(l1)
    

    4、循环提示用户输入,并将输入内容追加到集合中(如果输入N或者n则停止循环)

    set1 = {1,3,'mrxing',4,'小米',False,'天气'}
    while 1:
        a = input('请输入需要追加到集合的内容,如果退出输入n:')
        if a.upper() == 'N':
            print('程序结束~!')
            break
        else:
            set1.add(a)
        print(set1)
    

    5、看代码判断结果

    info = [1, 2, 3]
    user_list = []
    for item in range(10):
        user_list.append(info)
    info[1] = '是谁说python好学的?'
    print(user_list)
    

    结果输出:

    [[1, '是谁说python好学的?', 3], [1, '是谁说python好学的?', 3], [1, '是谁说python好学的?', 3], [1, '是谁说python好学的?', 3], [1, '是谁说python好学的?', 3], [1, '是谁说python好学的?', 3], [1, '是谁说python好学的?', 3], [1, '是谁说python好学的?', 3], [1, '是谁说python好学的?', 3], [1, '是谁说python好学的?', 3]]
    

    七、7的倍数游戏

    让用户随便输入数字,从1开始数数,遇到7或7的倍数时侧在列表中添加一个'咣'

    num = int(input('请输入随便一个数字:'))
    ls=[]
    for i in range(1,num+1):
        if str(i).find('7') == -1 and i % 7 != 0 :  #把i转成字符串,使用find方法(字符串中不包含时,返回-1)
            ls.append(i)
        else:
            ls.append('咣')
    print(ls)
    
  • 相关阅读:
    __cdecl, __stdcall, __fastcall,__pascal调用区别
    Windows Hook原理与实现
    C语言四大存储区域总结
    MFC DestroyWindow、OnDestroy、OnClose 程序关闭相关
    VC++动态链接库DLL编程深入浅出"
    windows 安全模型简介
    获取当前焦点窗口进程名
    获取IE URL
    DLL编写中extern “C”和__stdcall的作用
    Django2支持跨域方法
  • 原文地址:https://www.cnblogs.com/mr-xiong/p/13171847.html
Copyright © 2020-2023  润新知