is == id 用法, 代码块,缓存机制,深浅copy,集合

01 内容大纲

  1. is == id 用法
  2. 代码块
  3. 同一代码块下的缓存机制
  4. 不同代码块下的缓存机制(小数据池)
  5. 总结
  6. 集合(了解)
  7. 深浅copy

02 具体内容

1.id is ==

  • id是内存地址。 你只要创建一个数据(对象)那么都会在内存中开辟一个空间,将这个数据临时加在到内存中,那么这个空间是有一个唯一标识的,就好比是身份证号,标识这个空间的叫做内存地址,也就是这个数据(对象)的id。可以利用id()去获取这个数据的内存地址。
  • == 是比较的两边的数值是否相等。
  • is 是比较的两边的内存地址是否相等。 如果内存地址相等,那么这两边其实是指向同一个内存地址。
  • 如果内存地址id相同,那么值肯定相同,但是如果值相同,内存地址id不一定相同
  • id is == 三个方法要会用,知道是做什么的。
  # id 相当于身份证号
 i = 100
 print(id(i))#1366718576
 s = 'alex'
 print(id(s))#2321428227272

 # == 比较的是两边的值是否相等
 l1 = [1,2,3]
 print(id(l1))#2773818942472
 l2 = [1,2,3]
 print(id(l2))#2773819744136
 print(l1 == l2)# True   如果值相同,内存地址id不一定相同

 s1 = 'alex'
 print(id(s1))#2147747407048
 s2 = 'alex '
 print(id(s2))#2147777344096
 print(s1 == s2)#False

# is 判断的是内存地址是否相同
 l1 = [1, 2, 3]
 l2 = [1, 2, 3]
 print(id(l1))#1693709444104   同一代码块下,list不适用同一个代码块下的缓存机制
 print(id(l2))#1693710245768
 print(l1 is l2)#False      值相同,内存地址id不一定相同

 s1 = 'alex'
 s2 = 'alex'
 print(id(s1))#2941129958600
 print(id(s2))#2941129958600
 print(s1 is s2)#True
 print(s1 == s2)#True  # 内存地址id 相同,值一定相同

2.代码块

  • 代码块:我们所有的代码都需要依赖代码块执行。Python程序是由代码块构造的。块是一个python程序的文本,他是作为一个单元执行的。
  • 代码块:一个模块,一个函数,一个类,一个文件等都是一个代码块。
  • 交互式方式下一行就是一个代码块。(作为交互方式输入的每个命令都是一个代码块。)
  • 两个机制: 同一个代码块下,有一个机制。不同的代码块下,遵循另一个机制。

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

  • 前提条件:在同一个代码块内。
  • 机制内容:Python在执行同一个代码块的初始化对象的命令时,会检查是否其值是否已经存在,如果存在,会将其重用。换句话说:执行同一个代码块时,遇到初始化对象的命令时,他会将初始化的这个变量与值存储在一个字典中,在遇到新的变量时,会先在字典中查询记录,如果有同样的记录那么它会重复使用这个字典中的之前的这个值。
  • 适用的对象int bool str
  • 具体细则:所有的数字,bool,几乎所有的字符串。
    • int(float): 任何数字在同一代码块下都会复用。
    • bool: True和False在字典中会以1,0方式存在,并且复用。
    • str:几乎所有的字符串都会符合缓存机制,满足缓存机制则他们在内存中只存在一个,即:id相同。
  • 优点:提升性能,节省内存。
  • i1 = 1000
    i2 = 1000
    i3 = 1000
    print(id(i1))#1328495379536
    print(id(i2))#1328495379536
    print(id(i3))#1328495379536
    
    i = 800                                             ##int
    i1 = 800
    print(i is i1)  #True
    
    s1 = '[email protected]!#fkdjlsafjdskl;fjds中国'  ##str
    s2 = '[email protected]!#fkdjlsafjdskl;fjds中国'
    print(s1 is s2)  #True
    

4.不同代码块下的缓存机制--- 小数据池。

  • 小数据池,不同代码块的缓存机制,也称为小整数缓存机制,或者称为驻留机制。
  • 前提条件:在不同代码块内。
  • 机制内容:Python自动将-5~256的整数进行了缓存,当你将这些整数赋值给变量时,并不会重新创建对象,而是使用已经创建好的缓存对象。python会将一定规则的字符串在字符串驻留池中,创建一份,当你将这些字符串赋值给变量时,并不会重新创建对象, 而是使用在字符串驻留池中创建好的对象。
  • 适用的对象int bool str
  • 具体细则:-5~256数字【记】,bool,满足规则的字符串(小数据池下的数字和字符串的范围比同一代码块缓存机制时缩小了。)
    • int:对于整数来说,小数据池的范围是-5~256 ,如果多个变量都是指向同一个(在这个范围内的)数字,他们在内存中指向的都是一个内存地址。

      #交互式环境下,属于不同代码块,满足小数据池的数字范围是:-5~256
      >>> i = 100     #在-5~256内
      >>> i1 = 100
      >>> print(id(i))
      1366718576
      >>> print(id(i1))
      1366718576
      >>> print(i is i1)
      True
      
      >>> i2 = 1000   #不在范围内
      >>> i3 = 1000
      >>> print(id(i2))
      1928403259184
      >>> print(id(i3))
      1928403508080
      >>> print(i2 is i3)
      False
    • bool:bool值就是True,False,无论你创建多少个变量指向True,False,那么他在内存中只存在一个。
    • str:
  • 优点:提升性能,节省内存。

5.总结:

  1. 面试题考。
  2. 回答的时候一定要分清楚:如果在同一代码块下,则采用同一代码块下的换缓存机制。如果是不同代码块,则采用小数据池的驻留机制。
  3. 小数据池:数字的范围是-5~256.
  4. 缓存机制的优点:提升性能,节省内存。

6.集合set

  • 集合 set,容器型的数据类型,它要求它里面的元素是不可变的数据类型(int,str,bool,tuple),但是它本身是可变的数据类型。集合是无序的,不能按索引删除。{}。
  • 不可变的数据类型:int,str,bool,tuple 容器型的数据类型:list, tuple, dict, set
  • 集合的作用
    • 列表的去重:不能保留列表原来的顺序
    • 关系测试: 交集,并集,差集,.....(数据之间的关系)
    # 集合的创建:
        set1 = set({1,3,'barry',False})
        print(set1)#{False, 1, 'barry', 3}

        set1 = {1,3,'太白金星',4,'alex',False,'武大'}
        print(set1)#{False, 1, '武大', 3, 4, '太白金星', 'alex'}

        # 空集合:
        dic = {}    # 创建空字典
        print({}, type({}))  #{} <class 'dict'>

        set1 = set()  # 创建空集合
        print(set1) #set()

        # 集合的有效性测试:要求它里面的元素是不可变的数据类型
         set1 = {[1,2,3], 3, {'name':'alex'}}
         print(set1) #TypeError: unhashable type: 'list' 'dict'

        set1 = {'太白金星', '景女神',  '武大', '三粗', 'alexsb', '吴老师'}
    # 集合的增:
        # add
         set1.add('xx')
         print(set1)#{'景女神', 'xx', '三粗', '太白金星', 'alexsb', '吴老师', '武大'}
         set1.add('haha')
         print(set1)#{'景女神', 'xx', '三粗', 'haha', '太白金星', 'alexsb', '吴老师', '武大'}

        # update迭代着增加---->集合自动去重
         set1 = {'太白金星', '景女神',  '武大', '三粗', 'alexsb', '吴老师'}
         set1.update('derdfetg')
         print(set1)#{'g', 'alexsb', '三粗', 'e', '景女神', 'r', '吴老师', '太白金星', 'f', 'd', 't', '武大'}

    # 集合的删
    因为集合是无序的,所以不能按索引删除
        # remove :按照元素删除
          set1 = {'太白金星', '景女神',  '武大', '三粗', 'alexsb', '吴老师'}
          set1.remove('武大')
          print(set1)#{'alexsb', '吴老师', '三粗', '太白金星', '景女神'}
        # pop 随机删除一个元素
          set1 = {'太白金星', '景女神',  '武大', '三粗', 'alexsb', '吴老师'}
          set1.pop()
          print(set1)#{'武大', '太白金星', '吴老师', '三粗', 'alexsb'}
        #clear
         set1.clear()  # 清空集合
         print(set1)#set()

        #del
        del set1  # 删除集合
        print(set1)#NameError: name 'set1' is not defined

    # 变相改值:先删除,在增加
         set1 = {'太白金星', '景女神',  '武大', '三粗', 'alexsb', '吴老师'}
         set1.remove('太白金星')
         set1.add('男神')
         print(set1)#{'三粗', 'alexsb', '吴老师', '武大', '景女神', '男神'}

    #关系测试:***【重点】
        #  交集(&  或者 intersection)
         set1 = {1, 2, 3, 4, 5}
         set2 = {4, 5, 6, 7, 8}
         print(set1 & set2)#{4, 5}
         print(set1.intersection(set2))#{4, 5}

        # 并集:(| 或者 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(set1.union(set2))#{1, 2, 3, 4, 5, 6, 7, 8}

        # 差集:(- 或者 difference)
        set1 = {1, 2, 3, 4, 5}
        set2 = {4, 5, 6, 7, 8}
        print(set1 - set2)#{1, 2, 3} #求set1独有的
        print(set1.difference(set2))#{1, 2, 3}
        print(set2 - set1)#{8, 6, 7}

        # 反交集:(^ 或者 symmetric_difference)
         print(set1 ^ set2)#{1, 2, 3, 6, 7, 8}
         print(set1.symmetric_difference(set2))#{1, 2, 3, 6, 7, 8}

       # 子集
        set1 = {1,2,3}
        set2 = {1,2,3,4,5,6}
        print(set1 < set2)#True 说明set1是set2子集。
        print(set1.issubset(set2))#True

       # 超集
        set1 = {1,2,3}
        set2 = {1,2,3,4,5,6}
        print(set2 > set1)#True  说明set2是set1超集。
        print(set2.issuperset(set1))#True

        应用:列表的去重 ***【重点】 不能保留列表原来的顺序
         l1 = [1,'太白', 1, 2, 2, '太白',2, 6, 6, 6, 3, '太白', 4, 5, ]
         set1 = set(l1)
         l1 = list(set1)
         print(l1)#[1, 2, 3, 4, 5, 6, '太白']

        

7.深浅copy(面试会考,按代码的形式考)

  • 深浅copy其实就是完全复制一份,和部分复制一份的意思。
    # 赋值运算【面试题】
      对于赋值运算来说,l1与l2指向的是同一个内存地址id,所以他们是完全一样的。l1,l2指向的是同一个列表,任何一个变量对列表进行改变,剩下那个变量在使用列表之后,这个列表就是发生改变之后的列表。
        l1 = [1, 2, 3, [22, 33]]
        print(id(l1))#2999106822024
        l2 = l1   #赋值运算
        print(id(l2))#2999106822024
        l1.append(666)
        print(l1)#[1, 2, 3, [22, 33], 666]
        print(l2)#[1, 2, 3, [22, 33], 666]

        ####注意区分:(重新建了一个列表)
        l1 = [1, 2, 3, [22, 33]]
        l2 = [1, 2, 3, [22, 33]]
        print(id(l1))#2115308511112
        print(id(l2))#2115308545608
        l1.append(666)
        print(l1)#[1, 2, 3, [22, 33], 666]
        print(l2)#[1, 2, 3, [22, 33]]

    # 浅copy:
   对于浅copy来说,只是在内存中重新创建了开辟了一个空间存放一个新列表,但是新列表中的元素与原列表中的元素是公用的。
    #1:
     l1 = [1, 2, 3, [22, 33]]
     l2 = l1.copy()
     l1.append(666)
     print(l1,id(l1))#[1, 2, 3, [22, 33], 666] 2632840208264
     print(l2,id(l2))#[1, 2, 3, [22, 33]] 2632840243464

    #2: 浅copy只是copy了一个外壳,里面所有内容指向原来的。所以l1和l2的id不同,但是里面内容的id相同。
    l1 = [1, 2, 3, [22, 33]]
    l2 = l1.copy()
    l1[-1].append(666)
    print(id(l1))#1717681938312      列表id不同
    print(id(l2))#1717681973512
    print(id(l1[-1]))#1717681136648  内容id相同
    print(id(l2[-1]))#1717681136648
    print(id(l1[0]))#1366715408      内容id相同相同
    print(id(l2[0]))#1366715408
    print(id(l1[1]))#1366715440      内容id相同
    print(id(l2[1]))#1366715440
    print(l1)  #[1, 2, 3, [22, 33, 666]]
    print(l2)  #[1, 2, 3, [22, 33, 666]]

     #3.同一代码块下:
     l1 = [1, 2, 3, [22, 33],(1,2,3)]
     l2 = l1.copy()
     print(l1,id(l1))#[1, 2, 3, [22, 33], (1, 2, 3)] 1808473481096
     print(l2,id(l2))#[1, 2, 3, [22, 33], (1, 2, 3)] 1808473516296
     print(id(l1[-1]),id(l2[-1]))#1808473473672 1808473473672
     print(id(l1[-2]),id(l2[-2]))#1808472679432 1808472679432

     #4.
     l1 = [1, 2, 3, [22, 33]]
     l2 = l1.copy()
     l1[0] = 90
     print(l1)#[90, 2, 3, [22, 33]]
     print(l2)#[1, 2, 3, [22, 33]]

    # 深copy
    对于深copy来说,列表是在内存中重新创建的,列表中可变的数据类型是重新创建的,列表中的不可变的数据类型是公用的。
    python对深copy做了优化,将不可变的数据类型沿用同一个。
     import copy
    l1 = [1, 2, 3, [22, 33]]
    l2 = copy.deepcopy(l1)
    print(id(l1))#2336066990856
    print(id(l2))#2336066992136
    l1[-1].append(666)
    print(l1)#[1, 2, 3, [22, 33,666]]
    print(l2)#[1, 2, 3, [22, 33]]

    # 相关面试题;
    【注意】***list切片是浅copy***
     l1 = [1, 2, 3, [22, 33]]
     l2 = l1[:]
     l1[-1].append(666)
     print(l1)#[1, 2, 3, [22, 33,666]]
     print(l2)#[1, 2, 3, [22, 33,666]]

     区分:看是否共用一个嵌套的可变数据类型list,dict
     浅copy:嵌套的可变的数据类型(list dict)是同一个。
     深copy:嵌套的可变的数据类型(list dict)不是同一个 。

8.enumerate:枚举

对于一个可迭代的(iterable)/可遍历的对象(如列表、字符串),enumerate将其组成一个索引序列,利用它可以同时获得索引和值

# enumerate(iterable[, start])
l1 = ['a', 'b', 'c']
for i in enumerate(l1):  # [(0, 'a'),(1, 'b'),(2, 'c')]
    print(i)
# (0, 'a')
# (1, 'b')
# (2, 'c')

for i in enumerate(l1,start=100):  #起始位置默认是0,可更改
    print(i)
# (100, 'a')
# (101, 'b')
# (102, 'c')

li = ['alex','银角','女神','egon','太白']
for i in enumerate(li):
    print(i)
# (0, 'alex')
# (1, '银角')
# (2, '女神')
# (3, 'egon')
# (4, '太白')

for index,name in enumerate(li,1):
    print(index,name)
# 1 alex
# 2 银角
# 3 女神
# 4 egon
# 5 太白

for index, name in enumerate(li, 100):  # 起始位置默认是0,可更改
    print(index, name)
# 100 alex
# # 101 银角
# # 102 女神
# # 103 egon
# # 104 太白

原文地址:https://www.cnblogs.com/xiaomage666/p/10822732.html

时间: 2024-10-29 06:22:02

is == id 用法, 代码块,缓存机制,深浅copy,集合的相关文章

Python 小数据池、代码块以及代码块缓存机制

按照惯例,吟诗一首:苏轼<江城子·乙卯正月二十日夜记梦> 十年生死两茫茫,不思量,自难忘.千里孤坟,无处话凄凉. 纵使相逢应不识,尘满面,鬓如霜. 夜来幽梦忽还乡,小轩窗,正梳妆.相顾无言,惟有泪千行. 料得年年肠断处,明月夜,短松冈. 1. is 和 == 之间的区别 在讲解代码块及其缓存机制之前有必要搞清楚is和==之间的区别 开门见山直接说:==是比较两边变量的值是否相同,is是比较两边变量的内存地址是否相同,在python中内存地址如何获取,当然是使用id(item)函数获取了 举两个

is == id 的用法;代码块;深浅copy;集合

1 内容总览 is == id 用法 代码块 同一代码块下的缓存机制 (字符串驻留机制) 不同代码块下的缓存机制 (小数据池) 总结 集合(了解) 深浅copy 2 具体内容 id is == # id 获取对象的内存地址,内存地址就相当于人的身份证号,唯一且不可变 # i = 100 # s = 'alex' # print(id(i)) #1892120688 # print(id(s)) #2707107640912 # == 比较的是两边的值是否相等 l1 = [1, 2, 3] l2

Python代码块缓存、小数据池

引子 前几天遇到了这样一道Python题目:a='123',b='123',下列哪个是正确的? A. a != b B. a is b C. a==123 D. a + b =246 正确答案是B 是的,我选错了,我当时觉得没有正确答案,原因是我当时已经知道Python中 == 与 != 是比较两边的数值是否相等,很显然 a==b,我也知道 is 比较的是两边的内存地址是否相同,而内存地址是否相同是通过比较 id(a) 是否等于id(b)来知道的,而我想当然地认为a和b是两个不一样的变量,内存地

python 06 id is == set 深浅copy

01 今日内容大纲 is==id用法 代码块 同一代码下的缓存机制 不同代码下的缓存机制(小数据池) 总结 集合(了解,但金融有时候会用到) 深浅copy 02 昨日回顾 is id == 字典初识: 查询速度快,存储大量的关联性数据 键:是不可变数据类型,比如str bool int tuple,并且是唯一的 值:可以是任意数据类型,对象 字典3.5x之前是无序的,3.6x按照初始时的顺序排列,3.7之后是有序的 增删改查: 增:setdefault(),dic['age']=18 删:pop

python代码块和小数据池

id和is 在介绍代码块之前,先介绍两个方法:id和is,来看一段代码 1 # name = "Rose" 2 # name1 = "Rose" 3 # print(id(name)) 4 # print(id(name1)) # 两个id相同 5 # print(name == name1) # True 6 # print(name is name1) # True 执行结果 2257847297000 2257847297000 True True Proce

Python 代码块

代码块 骏马金龙https://www.cnblogs.com/f-ck-need-u/p/9925021.html https://www.cnblogs.com/jin-xin/articles/9439483.html 代码块可以使得一段python代码作为一个单元.一个整体执行. 几种代码块 模块文件是一个代码块 函数体是一个代码块 class的定义是一个代码块 交互式(python idle)的每一个命令行都是一个独立的代码块 脚本文件是一个代码块 脚本命令是一个代码块(python

利用php的ob缓存机制实现页面静态化

首先介绍一下php中ob缓存常用到的几个常用函数ob_start():开启缓存机制ob_get_contents():获取ob缓存中的内容ob_clean()清除ob缓存中的内容,但不关闭缓存ob_end_clean() 清除ob缓存中的内容,并关闭缓存ob_flush 清空缓存,输出内容,但不关闭缓存ob_end_flush 清空缓存,输出内容,并关闭缓存flush强制刷新输出缓存中的内容按照http协议的规定,回应内容不能在回应头之前输出,所以,如果在header()函数前面有内容输出,就会

Objective-C语法之代码块(block)的使用 (转载)

代码块本质上是和其他变量类似.不同的是,代码块存储的数据是一个函数体.使用代码块是,你可以像调用其他标准函数一样,传入参数数,并得到返回值. 脱字符(^)是块的语法标记.按照我们熟悉的参数语法规约所定义的返回值以及块的主体(也就是可以执行的代码).下图是如何把块变量赋值给一个变量的语法讲解: 按照调用函数的方式调用块对象变量就可以了:int result = myBlock(4); // result是 28 1.参数是NSString*的代码块 [cpp] view plain copy vo

关于构造代码块、局部代码块和静态代码块的作用和区别

构造代码块: 直接在类中定义且没有加static关键字的代码块称为{}构造代码; 作用:给对象统一初始化数据 public class Demo1 { public static void main(String[] args) { Test test = new Test(3); //构造代码块会在构造函数被调用时执行, 且在这个例子中比"this.id=id;"语句先执行,作用是给对象统一初始化数据; System.out.println(test); } } class Test