代码块、缓存机制、深浅拷贝、集合

  • id、is、==
  1. id: 可类比为身份号,具有唯一性,若id 相同则为同一个数据。
  1. #获取数据的内存地址(随机的地址:内存临时加载,存储数据,当程序运行结束后,内存地址即被丢弃):
  2. i = 'a'
  3. print(id(i))
  4. >>>2047746570672
  5. print(id(i))
  6. >>>2020558633392
  7. print(id(i))
  8. print(id(i))
  9. >>>1908036008368
  10. 1908036008368
  11. l1 = [1,2,3]
  12. l2 = [1,2,3]
  13. print(l1 == l2)
  14. >>>True #比较的是两边的值是否相等。
  1. is 判断id是否相同 (‘’==’‘判断值是否相同
  1. l1 = [1,2,3]
  2. l2 = [1,2,3]
  3. print(l1 is l2)
  4. >>>False #判断的是内存地址是否相同。
  5. print(id(l1))
  6. print(id(l2))
  7. >>>2648963830216
  8. 2648963830728
  9. l1 = [1,2,3]
  10. l2 = l1
  11. print(l1 is l2)
  12. print(id(l1))
  13. print(id(l2))
  14. >>>True
  15. 2053863395784
  16. 2053863395784
  17. s1 = 'iam'
  18. s2 = 'iam'
  19. print(s1 is s2)
  20. >>>True
  21. print(id(s1))
  22. print(id(s2))
  23. >>>2188534085552
  24. 2188534085552

​ id相同,值一定相同,值相同,id不一定相同。

  • 代码块:python的程序是由代码块构造的。块是一个python程序的脚本,它是作为一个单元执行的。一个模块,一个函数,一个类,一个文件等都是代码块。而作为互交命令方式输入的每个命令都是一个代码块。两个机制:如果在同一代码块下,则采用同一代码块下的换缓存机制。如果是不同代码块,则采用小数据池的驻留机制

    • 同一个代码块的缓存机制(字符串驻留机制):机制内容:Python在执行同一个代码块的初始化对象的命令时,会检查是否其值是否已经存在,如果存在,会将其重用。换句话说:执行同一个代码块时,遇到初始化对象的命令时,他会将初始化的这个变量与值存储在一个字典中,在遇到新的变量时,会先在字典中查询记录,如果有同样的记录那么它会重复使用这个字典中的之前的这个值,即:id相同。

      适用对象int(float)::任何数字在同一代码块下都会复用。

      str:几乎所有的字符串都会符合缓存机制(1,非乘法得到的字符串都满足代码块的缓存机制,,乘法得到的字符串分两种情况:1. 乘数为1时,任何字符串满足代码块的缓存机制,2. 乘数>=2时,仅含大小写字母,数字,下划线,总长度<=20,满足代码块的缓存机制)

      1. s1 = 'iam'*1
      2. s2 = 'iam'*1
      3. print(s1 is s2)
      4. >>>True

      bool:True和False在字典中会以1,0方式存在,并且复用。

      优点:能够提高一些字符串,整数处理人物在时间和空间上的性能;需要值相同的字符串,整数的时候,直接从‘字典’中取出复用,避免频繁的创建和销毁,提升效率,节约内存。

    • 在不同一个代码块内的缓存机制:小数据池,也称为小整数缓存机制,或者称为驻留机制等等。Python自动将-5~256的整数进行了缓存,当你将这些整数赋值给变量时,并不会重新创建对象,而是使用已经创建好的缓存对象。

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

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

      适用对象int(float):那么大家都知道对于整数来说,小数据池的范围是-5~256 ,如果多个变量都是指向同一个(在这个范围内的)数字,他们在内存中指向的都是一个内存地址。

      1. # pycharm 通过运行文件的方式执行下列代码: 这是在同一个文件下也就是同一代码块下,采用同一代码块下的缓存机制。
      2. i1 = 1000
      3. i2 = 1000
      4. print(i1 is i2) # 结果为True 因为代码块下的缓存机制适用于所有数字
      5. >>>True
      6. #通过交互方式中执行下面代码,这是不同代码块下,则采用小数据池的驻留机制。
      7. >>> i1 = 1000
      8. >>> i2 = 1000
      9. >>> print(i1 is i2)
      10. False # 不同代码块下的小数据池驻留机制 数字的范围只是-5~256.

      str:1.字符串的长度为0或者1,默认都采用了驻留机制(小数据池)。2.字符串的长度>1,且只含有大小写字母,数字,下划线时,才会默认驻留。3.用乘法得到的字符串,分两种情况:1 乘数为1,满足规则的字符串,默认驻留。2. 乘数>=2时:仅含大小写字母,数字,下划线,总长度<=20,默认驻留。

      1. #4.指定驻留
      2. from sys import intern
      3. a = intern('hello!@'*20)
      4. b = intern('hello!@'*20)
      5. print(a is b)
      6. >>>True
      7. #指定驻留是你可以指定任意的字符串加入到小数据池中,让其只在内存中创建一个对象,多个变量都是指向这一个字

      bool值就是True,False,无论你创建多少个变量指向True,False,那么他在内存中只存在一个。

      1. # 虽然在同一个文件中,但是函数本身就是代码块,所以这是在两个不同的代码块下,不满足小数据池(驻存机制),则指向两个不同的地址。
      2. def func():
      3. i1 = 1000
      4. print(id(i1)) # 2288555806672
      5. def func2():
      6. i1 = 1000
      7. print(id(i1)) # 2288557317392
      8. func()
      9. func2()

      优点:能够提高一些字符串,整数处理人物在时间和空间上的性能;需要值相同的字符串,整数的时候,直接从‘池’里拿来用,避免频繁的创建和销毁,提升效率,节约内存

参考文章:https://www.cnblogs.com/jin-xin/articles/9439483.html

  • 集合 (set):容器型数据类型,要求它里面的元素是不可变的数据(可哈希),但它本身是可变的数据类型(不可哈希)。集合是无序的。以{}存放数据。

    • 作用:列表的去重;关系的测试(交集,并集…)

      /1. 集合的创建:

      1. set = {1,2'a'}
      2. #空集合的表示:
      3. set1 = set() #set1 = {}表示空字典

      /2 . 增:add update()#迭代增加,有重复的则去重

      1. set1 = {1,2}
      2. set1.add('a')
      3. print(set1)
      4. >>>{'a', 1, 2} #集合无序
      5. set1.update('asdfdsa')
      6. print(set1)
      7. >>>{'a', 1, 2, 'f', 's', 'd'}

      /3. 删:remove()(按照元素删除,pop()随机删除,clear()清空集合 del 删除集合

      1. set1 = {'a', 1, 2, 'f', 's', 'd'}
      2. set1.remove('a')
      3. print(set1)
      4. >>>{1, 2, 's', 'f', 'd'}
      5. set1.pop()
      6. print(set1)
      7. >>>{2, 's', 'f', 'd'}
      8. set1.clear()
      9. print(set1)
      10. >>>{}
      11. del set1

      /4. 改:先删除再增加

    • 交、并、

      /1 . 交集。(&或者intersection) 集合共同有的元素

      1. set1 = {1,2,3}
      2. set2 = {2,3,4}
      3. print(set1 & set2) #or print(set1.intersection)
      4. >>>{2,3}

      /2. 并集。(|或者union)集合所有的元素

      1. set1 = {1,2}
      2. set2 = {2,3}
      3. print(set1 | set2) #or print(set1.union(set2))
      4. >>>{1,2,3}

      /3. 差集 ( - 或者difference) ,前一集合独有的元素

      1. set1 = {1,2,3,4,5}
      2. set2 = {2,4,6}
      3. print(set1 - set2) #or print(set1.difference(set2))
      4. >>>{1,3,5}

      /4 . 反交集。(^ 或者symmetric_difference)每个集合独有的元素

      1. set1 = {1,2,3,4,5}
      2. set2 = {3,4,5,6,7}
      3. print(set1 ^ set2) #or print(set1.symmetric_difference(set2))
      4. >>>{1,2,6,7}

      /5. 子集与超集

      1. set1 = {1,2}
      2. set2 = {1,2,3}
      3. print(set1 < set2)
      4. >>>True
      5. print(set1.issubset(set2)) #set1是set2的子集
      6. >>>True
      7. print(set2 > set1)
      8. >>>True
      9. print(set2.issuperset(set1)) #set2是set1的超集
      10. >>>True

      /6. frozenset()让集合变为不可变类型

      1. s = frozenset('qweasd')
      2. print(s,type(s))
      3. >>>frozenset({'q', 'e', 'w', 's', 'a', 'd'}) <class 'frozenset'>
  • 深浅copy

    • 浅copy:在内存中开辟一个新的空间存放copy的对象(列表、字典),但是里面的所有元素与被copy对象的里面的元素共用一个。

      1. l1 = [1,2]
      2. l2 = l1
      3. l1.append(3)
      4. print(l2)
      5. >>>[1,2,3] #l1,l2两变量指向同一个id(数据)
      6. #浅copy
      7. l3 = [1,2,['a']]
      8. l4 = l3.copy()
      9. l3.append(3)
      10. print(l3)
      11. >>>[1,2,['a'],3]
      12. print(l4)
      13. >>>[1,2,['a']]
      14. l3[-2].append(4) #or l4[-1].append(4)
      15. print(l3)
      16. >>>[1, 2, ['a', 4], 3]
      17. print(l4)
      18. >>>[1,2,['a',4]] #l4与l3列表中的数据id是相同的,但l4与l3列表id不相同,即l3中的每个元素与l4中的每个元素使用的是相同的一个id,但l4与l3用的不是同一个id。

      其实列表第一个一个的槽位,它储存的是对象的内存地址。浅拷贝仍然使用原来的对象的内存地址。对储存的可变对象可以进行更改;若改变不可变类型,则改变的不是不可变类型本身,而是变量的指向关系

  • 深copy,需导入模块copy(浅copy也可以导入copy模块),不可变的数据类型沿用之前的内存地址,可变的数据类型创建新的内存地址。

    1. import copy
    2. l3 = [1,2,['a']]
    3. l4 = copy.deepcopy(l3) #浅copy为 l4 = copy.copy(l3)
    4. l3[-1].append(3)
    5. print(l3)
    6. >>>[1,2,['a',3]]
    7. print(l4)
    8. >>>[1,2,['a']] #浅copy输出为 [1,2,['a',3]]
    9. #列表第一个一个的槽位,它储存的是对象的内存地址。深拷贝会创建一个新的对象的内存地址。

    python对深copy做了一个优化,将对象为不可变数据类型的内存地址沿用同一个,只重新再创建一份可变数据类型的内存地址。

    浅copy:(list,dict),嵌套的不可变的数据类型是同一个id,可变类型也是同一个id。

    深copy:(list,dict),嵌套的不可变的数据类型是同一个id,嵌套的可变的数据类型不是同一个id。

  1. l1 = [1,2,['a']]
  2. l2 = l1[:]
  3. l1[-1].append(3)
  4. print(l2)
  5. >>>[1,2,['a',3]] #切片是浅copy
  6. import copy
  7. l1 = [1,2,[3,4]]
  8. l2 = copy.copy(l1)
  9. l3 = copy.deepcopy(l1)
  10. print(l1[0] is l2[0])
  11. >>>True
  12. print(l2[0] is l3[0])
  13. >>>True
  14. print(l3[0] is l1[0])
  15. >>>True
  16. print(l1[2] is l2[2])
  17. >>>False
  18. print(l1 is l2)
  19. >>>False
  20. print(l3 is l1)
  21. >>>False
  22. #无论是浅copy还是深copy,都会创建一个新的数据类型,但是数据类型中的不可变数据类型都是同一个(id相同),深copy的可变数据类型不是同一个(id不同)。

补充内置函数:

  1. l1 = ['a','b','c']
  2. for i in enumerate(l1,start=50): #start可默认不写
  3. print(i)
  4. >>>(50, 'a')
  5. (51, 'b')
  6. (52, 'c')
  7. #小题试做,看代码写结果:
  8. #1:
  9. l1 = [1,2,3,[4,5]]
  10. l2 = [1,2,3,[4,5]]
  11. a = l1 == l2 #先看等号右边
  12. b = l1 is l2
  13. print(a) #True
  14. print(b) #False
  15. #2.
  16. data_list = []
  17. for i in range(10):
  18. data = {}
  19. data['age'] = i
  20. data_list.append(data)
  21. print(data)
  22. >>>{'age': 9}
  23. print(data_list)
  24. >>>[{'age': 0}, {'age': 1}, {'age': 2}, {'age': 3}, {'age': 4}, {'age': 5}, {'age': 6}, {'age': 7}, {'age': 8}, {'age': 9}]
  25. #对比:
  26. data_list = []
  27. data = {}
  28. for i in range(10):
  29. data['age'] = i
  30. data_list.append(data)
  31. print(data_list)
  32. >>>[{'age': 9}, {'age': 9}, {'age': 9}, {'age': 9}, {'age': 9}, {'age': 9}, {'age': 9}, {'age': 9}, {'age': 9}, {'age': 9}]
  33. import copy
  34. l1 = [1,2,{'name':'山就在那儿','number':[3,4,5]},6,7]
  35. l2 = copy.deepcopy(l1)
  36. print(l1[2] is l2[2]) #False
  37. print(l1[2]['name'] is l2[2]['name']) #True #同一代码块下的缓存机制,只适用于不可变对象
  38. print(l1[2]['number'] is l2[2]['number']) #False
  39. l1[2]['name']='a'
  40. print(l1[2])
  41. {'name': 'a', 'number': [3, 4, 5]}
  42. print(l2[2])
  43. {'name': '山就在那儿', 'number': [3, 4, 5]}

python基础学习day6的更多相关文章

  1. Python基础学习Day6 is id == 区别,代码块,小数据池 ---->>编码

    一.代码块 Python程序是由代码块构造的.块是一个python程序的文本,他是作为一个单元执行的. 代码块:一个模块,一个函数,一个类,一个文件等都是一个代码块. 而作为交互方式输入的每个命令都是 ...

  2. Day1 Python基础学习

    一.编程语言分类 1.简介 机器语言:站在计算机的角度,说计算机能听懂的语言,那就是直接用二进制编程,直接操作硬件 汇编语言:站在计算机的角度,简写的英文标识符取代二进制去编写程序,本质仍然是直接操作 ...

  3. 0003.5-20180422-自动化第四章-python基础学习笔记--脚本

    0003.5-20180422-自动化第四章-python基础学习笔记--脚本 1-shopping """ v = [ {"name": " ...

  4. Day1 Python基础学习——概述、基本数据类型、流程控制

    一.Python基础学习 一.编程语言分类 1.简介 机器语言:站在计算机的角度,说计算机能听懂的语言,那就是直接用二进制编程,直接操作硬件 汇编语言:站在计算机的角度,简写的英文标识符取代二进制去编 ...

  5. Python 基础学习 总结篇

    Python 基础学习总结 先附上所有的章节: Python学习(一)安装.环境配置及IDE推荐 Python学习(二)Python 简介 Python学习(三)流程控制 Python学习(四)数据结 ...

  6. (一)python基础学习

    根据廖雪峰老师的python教程写一些学习总结! Python基础学习 1.使用list和tuple (1)list Python内置的一种数据类型是列表:list.list是一种有序的集合,可以随时 ...

  7. python基础学习(起步)

    目录 python基础学习(起步) 变量 常量 变量的内存管理 python垃圾回收机制 变量的其他赋值方式 今日编程小题 本人能力有限,若有偏颇之处请读者大大不吝赐教! 祝大家每天都在成长! pyt ...

  8. Python基础学习二

    Python基础学习二 1.编码 utf-8编码:自动将英文保存为1个字符,中文3个字符.ASCll编码被囊括在内. unicode:将所有字符保存为2给字符,容纳了世界上所有的编码. 2.字符串内置 ...

  9. Python基础学习一

    Python基础学习一 1.变量与常量 变量名:大小写英文.数字.下划线的组合,数字不能开头 常量名:习惯上常量用大写字母命名,例如"PI" 2.多行输出 转义符:反斜杠(),如果 ...

随机推荐

  1. restful 和RPC 的区别

    https://www.cnblogs.com/Dong-Ge/articles/9577019.html

  2. SpringBoot + JPA + mariadb

    SpringBoot + JPA + MariaDB 源码:https://github.com/ldl326308/LiveGreen-SpringBoot.git JPA持久层方法名命名规则:

  3. 分布式文件系统与HDFS

    HDFS,它是一个虚拟文件系统,用于存储文件,通过目录树来定位文件:其次,它是分布式的,由很多服务器联合起来实现其功能,集群中的服务器有各自的角色. HDFS 的设计适合一次写入,多次读出的场景,且不 ...

  4. 亚马逊Prime会员的杀价,能说明会员+会越来越便宜吗?

    前段时间,京东又坑了!京东调整了物流方案--从原来的购物不满49元只需6元运费,调整到购物不满46元运费15元,运费猛涨了9元!原本京东PLUS会员每月有5张免运费券,但在运费涨价后运费券限制在6元, ...

  5. 通过virt-manager给Windowsxp系统配置virtio驱动

    在虚拟机的detail上添加一个硬件设备. 下载virtio.iso文件,我使用的版本126,具体的virtio驱动放到了10.2上的itest的目录中,使用可以找. 在配置中,添加virtio硬盘. ...

  6. Lego:美团点评接口自动化测试实践

    概述 接口自动化概述   众所周知,接口自动化测试有着如下特点: 低投入,高产出. 比较容易实现自动化. 和UI自动化测试相比更加稳定. 如何做好一个接口自动化测试项目呢? 我认为,一个“好的”自动化 ...

  7. openCryptoki安装

    什么是OpenCryptoki OpenCryptoki提供Linux下的PKCS#11库和工具,支持包括TPM和IBM加密硬件以及软件令牌. 目前(2019/05/06)最新release版为3.1 ...

  8. 码海拾遗:简单Socket(TCP)类实现

    最近刚开始啃Unix网络编程(卷1:套接字联网API),为加深TCP连接的建立和终止的理解与记忆,记下本文,方便以后翻看. 同时留下的还有简单的Socket(TCP)类: mySocket.h #pr ...

  9. 快速入门和查询Python

    评分: 4.5 作者: Ryan Lu 类别:Python 时间: 1. 注释 三种方式: 单行注释以 # 开头 多行注释用三个单引号 ''' 将注释括起来 多行注释用三个双引号 "&quo ...

  10. 使用Lucene.Net做一个简单的搜索引擎-全文索引

    Lucene.Net Lucene.net是Lucene的.net移植版本,是一个开源的全文检索引擎开发包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎. ...