zoukankan      html  css  js  c++  java
  • 集合、字典、哈希算法、变量的缓存机制、小数据池、强制类型转换

    1、集合

    1.1 定义:set表示集合,用{}表示,内部的数据用逗号隔开,如果是一个空的集合,需要定义成setvar = set(),

    1.2 特点:集合是无序的,没有索引的概念;集合是可变类型,集合内的元素必须是不可变类型;集合内的元素必须是不重复的,所以利用集合可以去重

    1.3 作用:去重、关系运算

    1.4集合关系运算演示

    (1)并运算:|符号代表集合的并运算   union()

    a = {"牛肉","青菜","鸡蛋","米饭","牛奶"}
    b = {"猪肉","蔬菜","鸭蛋","米饭","牛奶"}
    res = a|b  # a.union(b)
    print(res) # {'蔬菜', '牛奶', '鸭蛋', '米饭', '鸡蛋', '青菜', '猪肉', '牛肉'}

    (2)交运算:&符号代表集合的交运算  intersection()

    a = {"牛肉","青菜","鸡蛋","米饭","牛奶"}
    b = {"猪肉","蔬菜","鸭蛋","米饭","牛奶"}
    res = a&b  # a.intersection(b)
    print(res) # {'牛奶', '米饭'}

    (3)减运算:- 代表集合的减法操作,减掉一样的,剩下自己独有的  difference()

    a = {"牛肉","青菜","鸡蛋","米饭","牛奶"}
    b = {"猪肉","蔬菜","鸭蛋","米饭","牛奶"}
    res = a-b # a.difference(b)
    print(res) # {'青菜', '牛肉', '鸡蛋'}

    (4)对称差集:去掉两个集合重复的部分  symmetric_difference()

    a = {"牛肉","青菜","鸡蛋","米饭","牛奶"}
    b = {"猪肉","蔬菜","鸭蛋","米饭","牛奶"}
    res = a^b  a.symmetric_difference(b)
    print(res) # {'蔬菜', '鸭蛋', '猪肉', '青菜', '鸡蛋', '牛肉'}

    (5)判断两个集合是否相等:==

    a = {"牛肉","青菜","鸡蛋","米饭","牛奶"}
    b = {"猪肉","蔬菜","鸭蛋","米饭","牛奶"}
    res = a==b
    print(res) # False

    (6)判断一个集合是否包含另外一个集合:>     (同理,用<符号可以判断一个集合是否属于另一个集合)  issubset

    a = {"牛肉","青菜","鸡蛋","米饭","牛奶"}
    b = {"猪肉","蔬菜","鸭蛋","米饭","牛奶"}
    res = a>b a.issubset(b)
    print(res) # False

    1.5集合去重演示

    注意:集合去重具有局限性,元素必须是不可变类型,并且去重后不能保持原来的顺序

    l = ["黄色","蓝色","白色","紫色","蓝色","黄色"]
    tuplevar = set(l)
    l = list(tuplevar)
    print(l) #['白色', '蓝色', '黄色', '紫色']

    2、字典

    1.1 定义:以{}来表示,里面的值以键值对表示,键和值之间用冒号连接,键值对之间用逗号表示,如果是一个空的字典,则可直接用dictvar = {}表示

    1.2 要求:字典的键必须是不可改变的类型,可以根据字典的键来更改字典的值,如下代码

    dictvar = {"name":"bob","age":27,"hobby":"run"}
    dictvar["hobby"] = "walk"
    print(dictvar) #{'name': 'bob', 'age': 27, 'hobby': 'walk'}

    3、哈希算法

    3.1 定义:是把任意长度的输入,通过散列算法变成固定长度的输出值,该输出值就是散列值。哈希的输入可以是数据也可以是文件

    3.2 特点:(1)哈希算法不可逆,不能根据结果推算出输入值,故称不可逆算法

                    (2)哈希算法计算速度快,不管输入内容有多大,都可以在很短的时间内得到哈希值

    3.3 作用:(1)用于密码存储,在网上所设置的密码基本都是经过哈希算法后再存进数据库的,确保密码不会轻易泄露

                    (2)用于文件完整性校验,若文件被改动过,则此文件的哈希值也会更改

                    (3)数字签名

    3.4 字典和集合数据存储都是基于哈希算法

            字典的key是通过哈希算法得到的哈希值然后按照顺序来存储的,所以当一个字典中有大量的数据,而我们需要查找某一个数据时,通过二分法来找到这个数据对应的哈希值,从而找到这个数据的值,极大的节省了时间,这也是字典查找速度快的原因。

            集合里面的数据也都会先经过哈希算法,然后存储,当相同的值进来时,由于哈希值相同,所以集合会自动把相同的值去掉

    4、变量的缓存机制(节省内存空间)

    (1)整型(int):在-5到正无穷之间的数字,id是一样的,这样设置可以节省内存空间(针对在python3.6版本里,在3.6以上版本里,所有数字的id都是一样的)

    a = 10
    b = 10
    print(id(a),id(b)) #1554284944 1554284944
    c = -18
    d = -18
    print(id(c),id(d)) # 2259626609168 2259626609552

    (2)浮点型(float):非负数字的值一样,则id一样

    a = 3.3
    b = 3.3
    c= -12
    d = -12
    print(id(a),id(b)) # 2600578584960 2600578584960
    print(id(c),id(d)) # 2600588331536 2600588331920

    (3)布尔值(bool):布尔值一样的,id就是一样的

    a = False
    b = False
    c = True
    d = True
    print(id(a),id(b),id(c),id(d))
    # 1553779152 1553779152 1553779120 1553779120

    (4)复数(complex):在实数+虚数的情况下,id值必不相同,在只有虚数的情况下,值一样的,id也一样

    a = 5+3j
    b = 5+3j
    c = 3j
    d = 3j
    print(id(a),id(b),id(c),id(d))
    # 2284284791632 2284284791600 2284283988880 2284283988880

    (5)字符串、空元祖:字符串值一样的,id就一样,空的元祖,id一样

    name = "bob"
    name1 = "bob"
    set1 = ()
    set2 = ()
    print(id(name),id(name1),id(set1),id(set2))
    # 2510279536912 2510279536912 2510249459784 2510249459784

    (6)列表、字典、集合在任何情况下id都不一样

    (7)小数据池:仅针对于int、str、bool、空元祖()、None

            int整型:在-5到256之间的整数,提前驻留在内存的部分空间里,所以在不同文件里,如果定义值是-5到256之间的整数,则id一样

            str字符串:如果字符串的长度为0或者1,默认驻留小数据池,

    s1 = "a"
    s2 = "a"
    print(s1 is s2) #True

                             如果字符串的长度大于1,且只含有大小写字母、数字、下划线时,默认驻留小数据池

    s1 = "sfsjWES__345"
    s2 = "sfsjWES__345"
    print(s1 is s2) # True

                           如果用*得到的字符串,乘数等于1时,默认驻留小数据池,如果乘数大于1时,仅包含数字、字母、下划线、会被缓存,但长度不能大于20

    s1 = "我不知道你知不知道"
    s2 = s1*1
    print(s1 is s2) # True
    
    s3 = "j_8"*2
    s4 ="j_8"*2
    print(s3 is s4) # True
    
    s5 = "j_8dsd"*20
    s6 = "j_8dsd"*20
    print(s5 is s6) #False

                     默认保留小数据池,导入intern函数,可以让两个变量指向同一个值

    c = "我现在在敲代码"*10
    d = "我现在在敲代码"*10
    print(c is d) # False
    
    from sys import intern
    a = intern("我现在在敲代码"*10)
    b = intern("我现在在敲代码"*10)
    print(a is b) #True

    5、强制类型转换

    5.1 number类型(int、float、bool、complex)

    5.1.1 int类型:

    intvar = 3
    floatvar = 3.33
    boolvar = True
    boolvar1 = False
    complex = 5+3j
    complex1 = 3j

    int2 = int(floatvar) print(int2) #3

    int3 = int(boolvar) int4 = int(boolvar1) print(int3) # 1 print(int4) # 0

    int5 = int(complex) int6 = int(complex1) print(int5) #TypeError: can't convert complex to int print(int6) #TypeError: can't convert complex to int

    总结:int可以将float、bool和纯数字的字符串转化成int ,其中在将float转成int时,直接将小数部分去掉,在将bool转成int时,True转成1,Flase转成0。int不能转化complex

    5.1.2 float类型:

    intvar = 3
    floatvar = 3.6
    boolvar = True
    boolvar1 = False
    complex = 5+3j
    complex1 = 3j
    
    floatvar1 = float(intvar)
    print(floatvar1) #3.0
    
    floatvar2 = float(boolvar)
    floatvar3 = float(boolvar1)
    print(floatvar2) #1.0
    print(floatvar3) #0.0
    
    floatvar4 = float(complex)
    floatvar5 = float(complex1)
    print(floatvar4) #TypeError: can't convert complex to float
    print(floatvar5) #TypeError: can't convert complex to float

    总结:float可以将int、bool和纯数字的字符串转化成float,但是不能将complex转化成float

     5.1.3 bool类型:

    intvar = 3
    floatvar = 3.6
    boolvar = True
    boolvar1 = False
    complex = 5+3j
    complex1 = 3j
    
    bool1 = bool(intvar)
    print(bool1) # True
    
    bool2 = bool(floatvar)
    print(bool2) #True
    
    bool3 = bool(complex)
    bool4 = bool(complex1)
    print(bool3) #True
    print(bool4) # True

    总结:bool可以将几乎任何类型转化成bool

    在以下十种情况下,bool转化的值为假:

    0、0.0、0j、Flase、[]、set{}、()、{}、空字符串、None

    5.1.2 complex类型:

    intvar = 3
    floatvar = 3.6
    boolvar = True
    boolvar1 = False
    complex1 = 5+3j
    complex2 = 3j
    
    complexvar = complex(intvar)
    print(complexvar) # (3+0j)
    
    complexvar1 = complex(floatvar)
    print(complexvar1) # (3.6+0j)
    
    complexvar2 = complex(boolvar)
    complexvar3 = complex(boolvar1)
    print(complexvar2) # (1+0j)
    print(complexvar3) # 0j

    总结:complex可以将int、float、bool和纯数字的字符串转化成complex

    5.2 number类型运算:自动类型转化仅针对于number类型,将精确度低的转化为精确度高的,然后再计算

    int1 = 3
    float1 = 4.5
    print(int1+float1) #7.5
    
    int1 = 3
    float1 = 4.5
    bool1 = True
    complex1 = 2+3j
    print(int1+float1+bool1+complex1) # (10.5+3j)

    精确度从低到高:bool < int < float < complex

    5.2 容器类型

     5.2.1 str类型:

    str1 = "我是一朵向日葵"
    list1= ["桃花","梅花","荷花","梨花"]
    tuple1 = ("水仙花","玫瑰花","太阳花")
    set1 = {"郁金香","康乃馨","满天星"}
    dict1 = {"红色":"枸杞","白色":"桂圆"}
    
    strvar1 = str(list1)
    print(strvar1) # ['桃花', '梅花', '荷花', '梨花']
    strvar2 = repr(strvar1)
    print(strvar2) # "['桃花', '梅花', '荷花', '梨花']"
    #repr()可以原型化输出字符串,不转义,显示出引号
    
    strvar3 = str(tuple1)
    print(strvar3) # ('水仙花', '玫瑰花', '太阳花')
    
    strvar4 = str(set1)
    print(strvar4) # {'康乃馨', '满天星', '郁金香'}
    
    strvar5 = str(dict1)
    print(strvar5) #{'红色': '枸杞', '白色': '桂圆'

    总结:str可以将容器类型转化为字符串,包括number类型

    5.2.2 列表类型:

    str1 = "我是一朵向日葵"
    list1= ["桃花","梅花","荷花","梨花"]
    tuple1 = ("水仙花","玫瑰花","太阳花")
    set1 = {"郁金香","康乃馨","满天星"}
    dict1 = {"红色":"枸杞","白色":"桂圆"}
    
    listvar1 = list(str1)
    print(listvar1) # ['我', '是', '一', '朵', '向', '日', '葵']
    
    listvar2 = list(tuple1)
    print(listvar2) # ['水仙花', '玫瑰花', '太阳花']
    
    listvar3 = list(set1)
    print(listvar3) # ['郁金香', '康乃馨', '满天星']
    
    listvar4 = list(dict1)
    print(listvar4) # ['红色', '白色']

    总结:list可以将容器类型和number类型转化成list,如果是字符串,就把每一个单独的字符作为一个元素放到列表中,如果是字典,就只会将字典的key放到列表中

    5.2.3 元祖类型:

    str1 = "我是一朵向日葵"
    list1= ["桃花","梅花","荷花","梨花"]
    tuple1 = ("水仙花","玫瑰花","太阳花")
    set1 = {"郁金香","康乃馨","满天星"}
    dict1 = {"红色":"枸杞","白色":"桂圆"}
    
    tuplevar1 = tuple(str1)
    print(tuplevar1) # ('我', '是', '一', '朵', '向', '日', '葵')
    
    tuplevar2 = tuple(tuple1)
    print(tuplevar2) # ('水仙花', '玫瑰花', '太阳花')
    
    tuplevar3 = tuple(set1)
    print(tuplevar3) # ('康乃馨', '郁金香', '满天星')
    
    tuplevar4 = tuple(dict1)
    print(tuplevar4) # ('红色', '白色')

    总结:tuple可以将其他容器类型转换为元祖,如果是字符串,就把每一个单独的字符作为一个元素放到元祖中,如果是字典,就只会将字典的key放到元祖中

    5.2.4 集合类型:

    str1 = "我是一朵向日葵"
    list1= ["桃花","梅花","荷花","梨花"]
    tuple1 = ("水仙花","玫瑰花","太阳花")
    set1 = {"郁金香","康乃馨","满天星"}
    dict1 = {"红色":"枸杞","白色":"桂圆"}
    
    setvar1 = set(str1)
    print(setvar1) # {'一', '日', '朵', '葵', '是', '我', '向'}
    
    setvar2 = set(tuple1)
    print(setvar2) # {'太阳花', '水仙花', '玫瑰花'}
    
    setvar3 = set(set1)
    print(setvar3) # {'康乃馨', '满天星', '郁金香'}
    
    setvar4 = set(dict1)
    print(setvar4) # {'红色', '白色'}

    总结:set可以将其他容器类型转换为集合,如果是字符串,就把每一个单独的字符作为一个元素放到集合中,如果是字典,就只会将字典的key放到集合中。注意:集合有无序性和去重性

    5.2.5 字典类型:

    要求:必须是等长的二级容器,元素个数为两个

            (1)若外层是列表,里层是元祖或者列表(推荐)

    l1 = [["红色","枸杞"],("白色","桂圆")]
    dict1 = dict(l1)
    print(dict1)

           (2)若里面是集合,原则上是可以的,但是不推荐(因为集合是无序的,可能会打乱顺序)

    l1 = [{"红色","枸杞"},{"白色","桂圆"}]
    dict1 = dict(l1)
    print(dict1) # {'红色': '枸杞', '桂圆': '白色'}

          (3)若里面用字符串也是可以的,仅限长度为2的字符串,也不推荐

    l1 = [("红色","枸杞"),"白色"]
    dict1 = dict(l1)
    print(dict1) # {'红色': '枸杞', '白': '色'}
    
    l1 = [("红色","枸杞"),"白色桂圆"]
    dict1 = dict(l1)
    print(dict1) # ValueError: dictionary update sequence element #1 has length 4; 2 is required

        (4)若外层是集合,则里层只能放可哈希的元祖类型

    l1 = {("红色","枸杞"),("白色","桂圆")}
    dict1 = dict(l1)
    print(dict1) # {'白色': '桂圆', '红色': '枸杞'}
    
    l1 = {("红色","枸杞"),["白色","桂圆"]}
    dict1 = dict(l1)
    print(dict1) # TypeError: unhashable type: 'list'
  • 相关阅读:
    通过远程linux shell传输文件
    Windows下 postgresql安装报错
    python安装tesserocr错误解决办法
    django makemigrations
    Windows下eric安装的几个小问题
    _WinMain结构
    python学习第七天——输入输出、file
    python学习第六天——模块的概念(重要)
    python学习第五天——函数(重点)
    python学习第四天——控制流
  • 原文地址:https://www.cnblogs.com/fdsimin/p/12809415.html
Copyright © 2011-2022 走看看