Python基础 day7 数据类型(集合、字典、浮点型float)

发布时间 2023-03-29 11:55:52作者: PPPsych

day7 数据类型(集合、字典、浮点型float)

课程概要:

  • set集合,一个不允许重复重复 & 可变类型(元素可哈希)。
  • dict字典,一个容器且元素必须是键值对。
  • float类型,我们生活中常见的小数。

一 集合 set

1.1 定义

集合是一个 无序可变不允许数据重复的容器

v1 = { 11, 22, 33, "alex" }
  • 无序,无法通过索引取值。

  • 可变,可以添加和删除元素。

    v1 = {11,22,33,44}
    v1.add(55)
    print(v1) # {11,22,33,44,55}
    
  • 不允许数据重复。

    v1 = {11,22,33,44}
    v1.add(22)
    print(v1) # {11,22,33,44}
    

一般什么时候用集合呢?

就是想要维护一大堆不重复的数据时,就可以用它。比如:做爬虫去网上找图片的链接,为了避免链接重复,可以选择用集合去存储链接地址。

注意:定义空集合时,只能使用v = set(),不能使用 v={}(这样是定义一个空字典)。

# 定义空列表
v1 = [] # 方式一
v11 = list() # 方式二

# 定义空元组
v2 = () # 方式一
v22 = tuple() # 方式二

# 定义空集合
v3 = set()

# 定义空字典
v4 = {} # 方式一
v44 = dict() # 方式二

1.2 独有功能

  1. .add()

    添加元素

    data = {"刘嘉玲", '关之琳', "王祖贤"}
    data.add("郑裕玲")
    print(data)
    
    data = set()
    data.add("周杰伦")
    data.add("林俊杰")
    print(data)
    
  2. .discard()

    删除元素

    data = {"刘嘉玲", '关之琳', "王祖贤","张曼⽟", "李若彤"}
    data.discard("关之琳") 
    print(data)
    
  3. .intersection()

    取交集

    s1 = {"刘能", "赵四", "⽪⻓⼭"}
    s2 = {"刘科⻓", "冯乡⻓", "⽪⻓⼭"}
    
    s4 = s1.intersection(s2) # 取两个集合的交集 
    print(s4) # {"⽪⻓⼭"}
    
    # 方法二
    s3 = s1 & s2   			  # 取两个集合的交集
    print(s3)
    
  4. .union()

    取并集

    s1 = {"刘能", "赵四", "⽪⻓⼭"}
    s2 = {"刘科⻓", "冯乡⻓", "⽪⻓⼭"}
    s4 = s1.union(s2) 		# 取两个集合的并集  {"刘能", "赵四", "⽪⻓⼭","刘科⻓", "冯乡⻓", }
    print(s4)
    
    # 方法二
    s3 = s1 | s2   			# 取两个集合的并集
    print(s3)
    
  5. .difference()

    取差集

    s1 = {"刘能", "赵四", "⽪⻓⼭"}
    s2 = {"刘科⻓", "冯乡⻓", "⽪⻓⼭"}
    s4 = s1.difference(s2) 		# 差集,s1中有且s2中没有的值 {"刘能", "赵四"}
    s6 = s2.difference(s1)   	# 差集,s2中有且s1中没有的值 {"刘科⻓", "冯乡⻓"}
    
    # 方法二
    s3 = s1 - s2   			   # 差集,s1中有且s2中没有的值
    s5 = s2 - s1   			   # 差集,s2中有且s1中没有的值
    
    print(s5,s6)
    

1.3 公共功能

  1. 减,计算差集

    s1 = {"刘能", "赵四", "⽪⻓⼭"}
    s2 = {"刘科⻓", "冯乡⻓", "⽪⻓⼭"}
    
    s3 = s1 - s2 
    s4 = s2 - s1
    print(s3)
    print(s4)
    
  2. &,计算交集

    s1 = {"刘能", "赵四", "⽪⻓⼭"}
    s2 = {"刘科⻓", "冯乡⻓", "⽪⻓⼭"}
    s3 = s1 & s2
    print(s3)
    
  3. |,计算并集

    s1 = {"刘能", "赵四", "⽪⻓⼭"}
    s2 = {"刘科⻓", "冯乡⻓", "⽪⻓⼭"}
    s3 = s1 | s2
    print(s3)
    
  4. 长度

    v = {"刘能", "赵四", "尼古拉斯"}
    data = len(v)
    print(data)
    
  5. for循环

    v = {"刘能", "赵四", "尼古拉斯"}
    for item in v:
    	print(item)
    

1.4 转换

其他类型如果想要转换为集合类型,可以通过set进行转换,并且如果数据有重复自动剔除。

提示:int/list/tuple/dict都可以转换为集合。

v1 = "武沛齐"
v2 = set(v1)
print(v2) # {"武","沛","齐"}
v1 = [11,22,33,11,3,99,22]
v2 = set(v1)
print(v2) # {11,22,33,3,99}
v1 = (11,22,3,11)
v2 = set(v1)
print(v2) # {11,22,3}

提示:转换为集合其实也是去重的一个手段。

集合转换为其他类型:

data = {11,22,33,3,99}

v1 = list(data) # [11,22,33,3,99]

v2 = tuple(data) # (11,22,33,3,99)

1.5 其他

1.5.1 集合的存储原理

1.5.2 元素必须可哈希

因存储原理,集合的元素必须是可哈希的值,即:内部通过通过哈希函数把值转换成一个数字。

目前可哈希的数据类型:int、bool、str、tuple,而list、set是不可哈希的。

总结:集合的元素只能是 int、bool、str、tuple 。

  • 转换成功

    v1 = [11,22,33,11,3,99,22]
    v2 = set(v1)
    print(v2) # {11,22,33,3,99}
    
  • 转换失败

    v1 = [11,22,["alex","eric"],33]
    v2 = set(v1) # 报错 
    print(v2) 
    

1.5.3 查找速度特别快

因存储原理特殊,集合的查找效率非常高(数据量大了才明显)。

  • user_list = ["武沛齐","alex","李璐"]
    if "alex" in user_list:
        print("在")
    else:
        print("不在")
        
        
    user_tuple = ("武沛齐","alex","李璐")
    if "alex" in user_tuple:
        print("在")
    else:
        print("不在")
    
  • 效率高

    user_set = {"武沛齐","alex","李璐"}
    if "alex" in user_set:
        print("在")
    else:
        print("不在")
    

1.5.4 对比和嵌套

类型 是否可变 是否有序 元素要求 是否可哈希 转换 定义空
list list(其他) v=[]或v=list()
tuple tuple(其他) v=()或v=tuple()
set 可哈希 set(其他) v=set()
data_list = [
    "alex",
    11,
    (11, 22, 33, {"alex", "eric"}, 22),
    [11, 22, 33, 22],
    {11, 22, (True, ["中国", "北京"], "沙河"), 33} # 此处会报错,集合要求其元素必须是可哈希的,并且要求集合的元素子子孙孙都必须可哈希
]

注意:由于True和False本质上存储的是 1 和 0 ,而集合又不允许重复,所以在整数 0、1和False、True出现在集合中会有如下现象:

v1 = {True, 1}
print(v1)  # {True}

v2 = {1, True}
print(v2)  # {1}

v3 = {0, False}
print(v3)  # {0}

v4 = {False, 0}
print(v4)  # {False}

二 强插:None类型

Python的数据类型中有一个特殊的值None,意味着这个值啥都不是 或 表示空。 相当于其他语言中 null作用一样。

在一定程度上可以帮助我们去节省内存。例如:

# 内存消耗小
v1 = None
v2 = None
..
v1 = [11,22,33,44]
v2 = [111,22,43]
# 内存消耗大
v3 = []
v4 = []
...
v3 = [11,22,33,44]
v4 = [111,22,43]

因此目前所有转换为布尔值为False的值有:

0
""
[] or list()
() or tuple()
set()
None

同样可用于条件判断:

if None:
    pass

三 字典 dict

字典是 无序键不重复 且 元素只能是键值对可变的容器

data = { "k1":1,"k2":2 }
  • 容器

  • 元素必须键值对

  • 键不重复,重复则会被后面的键值对覆盖

    data = { "k1":1, "k1":2 }
    print(data) # {"k1":2}
    
  • 无序(在Python3.6+字典就是有序了,之前的字典都是无序。)

    data = { "k1":1,"k2":2 }
    print(data)
    

2.1 定义

# 方式一:
v1 = {}

# 方式二:
v2 = dict()
data = { 
    "k1":1, 
    "k2":2 
}
info = { 
    "age":12, 
    "status":True,  
    "name":"wupeiqi",   
    "hobby":['篮球','足球']  
}

字典中对键值得要求:

  • 键:必须可哈希

    目前为止学到的可哈希的类型:int/bool/str/tuple;不可哈希的类型:list/set/dict。

  • 值:任意类型。

data_dict = {
	"武沛齐":29,
	 True:5,
	123:5,
    (11,22,33):["alex","eric"] 
}
# 不合法
v1 = {
    [1, 2, 3]: '周杰伦',
    "age" : 18
} 
v2 = {
    {1,2,3}: "哈哈哈",
    'name':"alex"
} 

v3 = {
    {"k1":123,"k2":456}: '呵呵呵',
    "age":999
}

注意:字典跟集合类似,True底层为1(False为0),则当1和True作为键时则会使后面的键值对覆盖掉前面的键值对

data_dict = {
 1: 29,
 True: 5
}
print(data_dict) # {1: 5}

一般在什么情况下会用到字典呢?

当我们想要表示一组固定信息时,用字典可以更加的直观,例如:

# 用户列表
user_list = [ ("alex","123"), ("admin","666") ]
...
# 用户列表
# 使用字典
user_list = [ {"name":"alex","pwd":"123"}, {"name":"eric","pwd":"123"} ]

2.2 独有功能

  1. .get()

    通过键获取值

    info = { 
        "age":12, 
        "status":True, 
        "name":"武沛齐",
        "data":None
    }
    
    data1 = info.get("name")
    print(data1) # 输出:武沛齐
    
    data2 = info.get("age")
    print(data2) # 输出:12
    
    data = info.get("email") # 键不存在,默认返回 None
    
    """
    # 字典的键中是否存在 email
    if "email" in info:
        data = info.get("email")
        print(data)
    else:
    	print("不存在")
    """
    
    data = info.get("hobby",123) 
    # 若hooby键存在则获取其值,若不存在则返回123
    print(data) # 输出:123
    

    示例一:

    user_list = {
        "wupeiqi": "123",
        "alex": "uk87",
    }
    
    username = input("请输入用户名:")
    password = input("请输入密码:")
    # None,用户名不存在
    # 密码,接下来比较密码
    pwd = user_list.get(username)
    
    if pwd == None:
        print("用户名不存在")
    else:
        if password == pwd:
            print("登录成功")
    	else:
            print("密码错误")
    

    示例二:

    user_list = {
        "wupeiqi": "123",
        "alex": "uk87",
    }
    
    username = input("请输入用户名:")
    password = input("请输入密码:")
    # None,用户名不存在
    # 密码,接下来比较密码
    pwd = user_list.get(username)
    
    # 对示例一进行优化
    if pwd:
        if password == pwd:
            print("登录成功")
    	else:
            print("密码错误")
    else:
        print("用户名不存在")
    

    示例三:

    user_list = {
        "wupeiqi": "123",
        "alex": "uk87",
    }
    
    username = input("请输入用户名:")
    password = input("请输入密码:")
    # None,用户名不存在
    # 密码,接下来比较密码
    pwd = user_list.get(username)
    
    # 对示例二进行改变
    if not pwd:
        print("用户名不存在")
    else:
        if password == pwd:
            print("登录成功")
    	else:
            print("密码错误")
            
    # 建议使用此种方式        
    # 写代码的准则:简单的逻辑处理放在前面;复杂的逻辑放在后面。
    
  2. .keys()

    获取所有的键

    info = {"age":12, "status":True, "name":"wupeiqi","email":"xx@live.com"}
    data = info.keys()
    print(data) 
    # 输出:dict_keys(['age', 'status', 'name', 'email'])
    # py2 -> ['age', 'status', 'name', 'email']
    
    result = list(data)
    print(result) # ['age', 'status', 'name', 'email']
    

    注意:

    • 在Python2中 字典.keys()直接获取到的是列表
    • 而Python3中返回的是高仿列表,这个高仿的列表可以被循环显示。
    # 循环显示
    info = {"age":12, "status":True, "name":"wupeiqi","email":"xx@live.com"}
    for ele in info.keys():
        print(ele)
    
    # 判断键是否存在
    info = {"age":12, "status":True, "name":"wupeiqi","email":"xx@live.com"}
    # info.keys() # dict_keys(['age', 'status', 'name', 'email'])
    if "age" in info.keys():
        print("age是字典的键")
    else:
        print("age不是")
    
  3. .values()

    获取所有的值

    info = {"age":12, "status":True, "name":"wupeiqi","email":"xx@live.com"}
    data = info.values()
    
    print(data) 
    # 输出:dict_values([12, True, 'wupeiqi', 'xx@live.com'])
    

    注意:

    • 在Python2中 字典.values()直接获取到的是列表
    • 而Python3中返回的是高仿列表,这个高仿的列表可以被循环显示。
    # 循环显示
    info = {"age":12, "status":True, "name":"wupeiqi","email":"xx@live.com"}
    for val in info.values():
        print(val) 
    
    # 判断值是否存在
    info = {"age":12, "status":True, "name":"wupeiqi","email":"xx@live.com"}
    if 12 in info.values():
        print("12是字典的值")
    else:
        print("12不是")
    
  4. .items()

    获取所有的键值

    info = {"age":12, "status":True, "name":"wupeiqi","email":"xx@live.com"}
    data = info.items()
    
    print(data) 
    # 输出 dict_items([ ('age', 12),  ('status', True),  ('name', 'wupeiqi'),  ('email', 'xx@live.com')  ])
    # 同样是一个高仿列表,单次列表中每个元素是一个元组
    

    循环显示键值:

    for item in info.items():
        print(item[0],item[1]) 
        # item是一个元组 (键,值)
    
    for key,value in info.items():
        print(key,value) # key代表键,value代表值,将键值从元组中直接拆分出来了。
    

    判断键值是否存在:

    info = {"age":12, "status":True, "name":"wupeiqi","email":"xx@live.com"}
    data = info.items()
    
    if ('age', 12) in data:
        print("在")
    else:
        print("不在")
    
  5. .setdefault()

    设置值

    data = {
        "name": "武沛齐",
        "email": 'xxx@live.com'
    }
    data.setdefault("age", 18)
    print(data)  
    # {'name': '武沛齐', 'email': 'xxx@live.com', 'age': 18}
    
    data.setdefault("name", "alex")
    print(data)  
    # {'name': '武沛齐', 'email': 'xxx@live.com', 'age': 18}
    

    若键存在则不做任何操作,若键不存在则向字典添加键值对

  6. .update()

    更新字典键值对

    info = {"age":12, "status":True}
    info.update( {"age":14,"name":"武沛齐"} )   
    # info中没有的键直接添加;有的键则更新值
    
    print(info) 
    # 输出:{"age":14, "status":True,"name":"武沛齐"}
    

    没有的键直接添加键值对;有的键则更新其值

  7. .pop()

    移除指定键值对(可获取移除的值)

    info = {"age":12, "status":True,"name":"武沛齐"}
    
    data = info.pop("age")
    
    print(info) # {"status":True,"name":"武沛齐"}
    print(data) # 12
    
  8. .popitem()

    按照顺序移除(后进先出)

    info = {"age":12, "status":True,"name":"武沛齐"}
    data = info.popitem() # ("name","武沛齐" )
    
    print(info) # {"age":12, "status":True}
    print(data) # ("name","武沛齐")
    
    • py3.6后,popitem移除最后的值。
    • py3.6之前,popitem随机删除。

2.3 公共功能

  1. 并集(Python3.9新加入)

    v1 = {"k1": 1, "k2": 2}
    v2 = {"k2": 22, "k3": 33}
    
    v3 = v1 | v2
    print(v3) # {'k1': 1, 'k2': 22, 'k3': 33}
    
  2. 长度

    info = {"age":12, "status":True,"name":"武沛齐"}
    data = len(info)
    print(data) # 输出:3
    
  3. 是否包含

    判断键:

    info = { "age":12,  "status":True,"name":"武沛齐" }
    v1 = "age" in info # 默认判断键是否存在
    print(v1)
    
    v2 = "age" in info.keys() # v1等价于v2
    print(v2)
    

    判断值:

    info = {"age":12, "status":True,"name":"武沛齐"}
    v1 = "武佩奇" in info.values()
    print(v1)
    

    判断键值对:

    info = {"age": 12, "status": True, "name": "武沛齐"}
    # 输出info.items()获取到的 dict_items([ ('age', 12),  ('status', True),  ('name', 'wupeiqi'),  ('email', 'xx@live.com')  ])
    v1 = ("age", 12) in info.items()
    print(v1)
    
  4. 索引(键)
    字典不同于元组和列表,字典的索引是,而列表和元组则是 0、1、2等数值

    info = { "age":12,  "status":True, "name":"武沛齐"}
    
    print( info["age"] )  	    
    # 输出:12
    print( info["name"] )		
    # 输出:武沛齐
    print( info["status"] )	    
    # 输出:True
    print( info["xxxx"] )   	
    # 报错,通过键为索引去获取之后时,键不存在会报错(以后项目开发时建议使用get方法根据键去获取值)
    value = info.get("xxxxx") 
    print(value)
    # None
    
  5. 根据键 修改值 和 添加值 和 删除键值对
    修改/添加:

    info = {"age":12, "status":True,"name":"武沛齐"}
    
    info["gender"] = "男"
    
    print(info) # 输出: {"age":12, "status":True,"name":"武沛齐","gender":"男"}
    
    info = {"age":12, "status":True,"name":"武沛齐"}
    
    info["age"] = "18" 
    
    print(info) # 输出: {"age":"18", "status":True,"name":"武沛齐"}
    

    删除键值对:

    info = {"age":12, "status":True,"name":"武沛齐"}
    del info["age"]
    # info.pop("age")
    # 删除info字典中键为age的那个键值对(键不存在则报错)
    
    print(info) # 输出: {"status":True,"name":"武沛齐"}
    
    info = {"age": 12, "status": True, "name": "武沛齐"}
    if "agea" in info:
        # del info["age"]
        data = info.pop("age")
        print(info)
        print(data)
    else:
        print("键不存在")
    
  6. for循环
    由于字典也属于是容器,内部可以包含多个键值对,可以通过循环对其中的:键、值、键值进行循环;

    获取键:

    info = {"age":12, "status":True,"name":"武沛齐"}
    for item in info:
    	# 默认所有键
    	print(item)  
    
    info = {"age":12, "status":True,"name":"武沛齐"}
    for item in info.key():
    	print(item)
    

    获取值:

    info = {"age":12, "status":True,"name":"武沛齐"}
    for item in info.values():
    	print(item)
    

    获取键值对:

    info = {"age":12, "status":True,"name":"武沛齐"}
    for key,value in info.items():
    	print(key,value)
    

2.4 转换

转换为字典:

v = dict( [ ("k1", "v1"), ["k2", "v2"] ] )
print(v) # { "k1":"v1", "k2":"v2" }

转换为列表:

info = { "age":12, "status":True, "name":"武沛齐" }

v1 = list(info)        
# ["age","status","name"]

v2 = list(info.keys()) 
# ["age","status","name"]

v3 = list(info.values()) 
# [12,True,"武沛齐"]

v4 = list(info.items()) 
# [ ("age",12), ("status",True), ("name","武沛齐") ]

1.5 其他

1.5.1 存储原理

1.5.2 速度快

查找快

info = {
    "alex":["肝胆","铁锤"], 
	"老男孩":["二蛋","缺货"]
}
for "alex" in info:
    print("在")

获取快

info = {
    "alex":["肝胆","铁锤"], 
	"老男孩":["二蛋","缺货"]
}
v1 = info["alex"]
v2 = info.get("alex")

1.5.3 嵌套

注意一下几点:

  • 字典的键必须可哈希(list/set/dict不可哈希)。

    并且键的子子孙孙都必须可哈希

    # 可行
    info = {
        (11,22):123
    }
    
    # 错误
    info = {
        (11,[11,22,],22):"alex"
    }
    
  • 字典的值可以是任意类型。

    info = {
        "k1":{12,3,5},
    	"k2":{"xx":"x1"}
    }
    
  • 字典的键和集合的元素在遇到 布尔值10 时,需注意重复的情况。

  • 元组的元素不可以被替换。

四 浮点型 float

浮点型,一般在开发中用于表示小数。

v1 = 3.14
v2 = 9.89

关于浮点型的其他知识点如下:

  • 在类型转换时需要,在浮点型转换为整型时,会将小数部分去掉。

    v1 = 3.14 
    data = int(v1)
    print(data) # 3
    
  • 想要保留小数点后N位

    v1 = 3.1415926
    result = round(v1,3)
    # 自动四舍五入
    print(result) 
    # 3.142
    
  • 浮点型的坑(所有语言中)

    在项目中如果遇到精确的小数计算应该怎么办?

    # 使用decimal模块
    
    import decimal
    
    v1 = decimal.Decimal("0.1")
    v2 = decimal.Decimal("0.2")
    v3 = v1 + v2
    print(v3) # 0.3
    

总结

  1. 集合,是 无序、不重复、元素必须可哈希、可变的一个容器(子孙元素都必须是可哈希)。

  2. 集合的查找速度比较快(底层是基于哈希进行存储)

  3. 集合可以具有 交并差 的功能。

  4. 字典是 无序、键不重复 且 元素只能是键值对的可变的一个容器(键子孙元素都必须是可哈希)。

  5. py3.6+之后字典就变为有序了。

  6. py3.9 新增了一个 {} | {} 运算。

  7. 字典的常见功能。

  8. 在python2和python3中,字典的 keys() 、values()、items() 三个功能获取的数据类型不一样。

  9. None是代表内存中的一个空值。

  10. 浮点型用于表示小数,但是由于其内部存储原理可能会引发数据存储不够精准。