集合字典哈希算法变量的缓存机制小数据池强制类型转换

Posted fdsimin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了集合字典哈希算法变量的缓存机制小数据池强制类型转换相关的知识,希望对你有一定的参考价值。

1、集合

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

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

1.3 作用:去重、关系运算

1.4集合关系运算演示

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

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

 

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

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

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

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

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

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

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

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

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

a = {"牛肉","青菜","鸡蛋","米饭","牛奶"}
b = {"猪肉","蔬菜","鸭蛋","米饭","牛奶"}
res = a>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转化成int

 

 5.1.3 boll类型:

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可以将int、float、complex转化成bool,结果都为True

在以下十种情况下,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‘

 

以上是关于集合字典哈希算法变量的缓存机制小数据池强制类型转换的主要内容,如果未能解决你的问题,请参考以下文章

python的内存驻留机制(小数据池)

小数据池集合和深浅拷贝的个人理解

python 06 id is == set 深浅copy

小数据池 深浅拷贝 集合

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

python入门小数据池深浅拷贝集合