Lyf凤

靡不有初,鲜克有终

扩大
缩小

字典,集合

昨日回顾

     1. list列表
        写法:[元素, 元素]
        对元素的数据类型没有要求
        也有索引和切片
        索引从0开始
        切片
        lst[start: end: step]
            从start到end. 每隔step取一个

        增删改查
            1. 增加:
                1. append() 追加. 在列表的末尾添加
                2. insert(index, 元素) 在index位置插入元素

            2. 删除:
                1. pop(i) 默认从末尾删除, 还可以指定位置删除  ##返回删除的元素
                2. remove(元素) 删除指定元素
            3. 修改:
                通过索引去修改元素
                lst[3] = "胡辣汤"
            4. 查询:
                for item in lst: # 拿不到索引
                    print(item)

                for i in range(len(lst)):##能拿到索引,当需要输出索引或者需要对原来的列表进行修改的时候(对原列表的修改一定要使用索引)
                    print(i,lst[i])

        range(m) 从0到m
        range(m, n) 从m到n
        range(m, n, p) 从m到n. 每P个取一个

        for i in range(len(lst)):
            i  索引
            lst[i] 元素

        元组: 不可变的. 只读列表. 有索引. 有下标, 有切片.
            不可变: 内部指向

        可变的: list
        不可变的:str, int, bool, tuple

今日内容

    1. 什么是字典
        字典是以key:value的形式来保存数据
        用{}表示. 存储的是key:value
    2. 字典的增删改查(重点)
        1. 添加
            dic[新key] = 值

            setdefault(key,value) key不存在,添加键值对
        2. 删除
            pop(key) 删除指定键的键值对, #返回删除的键对应的值
            ## dic.popitem() # 随机删除一项(现在的版本一般是弹出最后一项)
            ##del dic["李安"]
            ##dic.clear() # 清空
        3. 修改
            dic[老key] = (新)值
            update() 更新字典(迭代更新,类似于列表的 extend)
        4. 查询
            dic[key]  ##直接使用key就可以拿到value
            get(key, 值) ##当key不存在. 返回第二个参数. 默认第二个参数是None
            setdefault(key, value)  key存在,返回对应的 value,key 不存在,先新增,再返回对应的 value
        5. 遍历,字典是一个可迭代对象

    3. 字典的相关操作
        1. keys() 获取到所有的键
        2. values() 获取到所有的值
        3. items() 拿到所有的键值对
    4. 字典的嵌套
        字典的嵌套. 字典套字典

    5. 集合(不重要). 去重复(##但是无序)
        集合中的元素是不重复的,必须是可哈希的(不可变), 相当于字典中的key(集合本身是可变的,但是它要求它内部的值是不可变的)
        空集合:set()
        空元组:tuple()
        空列表:list()
        非空集合: {123}集合, 集合其实就是不存value的字典(字典也是可变的,但是它要求他内部的 key 是不可变的)

    预习:
        深浅拷贝
        小数据池

        文件操作(带来的作业)

        函数


    # 关于set集合作业: 写一个彩票开奖(36选7)
    from random import randint
    randint(1,36)

字典

1. 字典的简单介绍

lst = ["周杰伦", "林俊杰", "蔡依林"]
lst[0] = "麻花藤"
# 相比列表,字典查找的效率比较高
# 坑: 字典存储数据的时候是用的hash值来存储. 哈希是一个算法,不能变的(python内置的)
# 数据必须是不可变的(可哈希). 字典的key必须是可哈希的(不可变).
dic = {"jay":"周杰伦", "jj": "林俊杰", "jolin":"蔡依林"}
print(dic['jay']) # 周杰伦
dic['jay'] = "麻花藤"

print(type(dic)) # <class 'dict'>

# 列表是可变的. 不可哈希
# 元组是不可变的. 可哈希的
print(hash((1,2,3)))
print(hash([1,2,3])) # TypeError: unhashable type: 'list'
dic = {"jay":"周杰伦", "王力宏":["龙的传人", "唯一", "改变自己"], ["战狼", "战狼2"]: "武警"}
print(dic)
View Code

 

字典(dict)是python中唯一的一个映射类型.他是以{ }括起来的键值对组成. 在dict中key是唯一的. 在保存的时候, 根据key来计算出一个内存地址. 然后将key-value保存在这个地址中. 这种算法被称为hash算法, 所以, 切记, 在dict中存储的key-value中的key'必须是可hash的,

如果你搞不懂什么是可哈希, 暂时可以这样记, 可以改变的都是不可哈希的, 那么可哈希就意味着不可变. 这个是为了能准确的计算内存地址而规定的.

已知的可哈希(不可变)的数据类型: int, str, tuple, bool

不可哈希(可变)的数据类型: list, dict, set

#语法 :
{key1: value1, key2: value2....}
注意: key必须是不可变(可哈希)的. value没有要求.可以保存任意类型的数据
# 合法
dic = {123: 456, True: 999, "id": 1, "name": 'sylar', "age": 18, "stu": ['帅 哥', '美女'], (1, 2, 3): '麻花藤'}
print(dic[123])
print(dic[True])
print(dic['id'])
print(dic['stu'])
print(dic[(1, 2, 3)])

# 不合法
dic = {[1, 2, 3]: '周杰伦'}  # list是可变的. 不能作为key
dic = {{1: 2}: "哈哈哈"}  # dict是可变的. 不能作为key
dic = {{1, 2, 3}: '呵呵呵'}  # set是可变的, 不能作为key
  

dict保存的数据不是按照我们添加进去的顺序保存的. 是按照hash表的顺序保存的. 而hash表不是连续的. 所以不能进⾏切片工作. 它只能通过key来获取dict中的数据

2. 字典增删改查和其他操作

dic = {"意大利": "李云龙", "美国": "美国往事"}


#
dic["日本"] = "东京审判"  # 新key表示添加
dic['韩国'] = "釜山行"

# setdefault (难点)
# 有添加的功能,如果key是存在的. 不添加
# 流程: 判断你给的key是否在字典中存在了.如果已经存在了. 就不再新增. 如果不存在. 执行新增操作
dic.setdefault("美国", "三傻大闹宝莱坞")
print(dic)


#
dic = {"张艺谋":"红高粱", "李安":"断臂山", "陈凯歌":"霸王别姬", "郭德纲":"祖宗十九代"}
dic.pop("郭德纲") # 你要记住的
print('>>>>>',dic.pop("郭德纲"))  # >>>>> 祖宗十九代
# dic.popitem() # 随机删除一项. 在python早期版本  字典是无序的.##现在是有序的(输出在屏幕上的显示是有序的,底层还是无序的),所以一般删除的是最后一项
del dic["李安"]
dic.clear() # 清空
print(dic)


#
dic = {"河南":"胡辣汤", "开封": "灌汤包", "武汉":"热干面"}
# dic['河南'] = "烩面" # 老key = 新值
print(dic)

dic1 = {"赵四":"刘晓光", "刘能":"王晓利", "王木生":"范伟"}
dic2 = {"赵四":"宝宝", "刘能":"萌萌", "皮校长":"皮长山"}
# 迭代更新
dic1.update(dic2) # 把dic2怼到dic1里面. 把dict2中的内容更新到dic1
print(dic1)
print(dic2)


#
dic1 = {"赵四":"刘晓光", "刘能":"王晓利", "王木生":"范伟"}

# 1. 直接使用key就可以拿到value
print(dic1["赵四四"]) # KeyError: '赵四四' key不存在


# 2. get(key)
print(dic1.get("刘能能"))  # None 当key不存在返回None
print(dic1.get("刘能能", "没有这个人")) # 当key不存在. 返回第二个参数. 默认第二个参数是None

# 3. setdefault() 第一个功能是添加(当key不存在). 第二个功能是查询(根据你给的key查询)
# 整个执行流程: 判断给的key是否存在. 如果存在. 就不执行新增流程.直接查询出这个key对应的value
# 如果key不存在. 先执行新增操作. 再使用key把对应的value查询出来
##这里是与 get(key,value)的区别,当 key不存在的时候,get不执行新增操作,直接返回你给定的 value 值,而 setdefault 先执行新增,再执行查询操作
ret = dic1.setdefault("皮长山", "皮校长")
print(ret) # 皮校长

ret = dic1.setdefault("王木生", "宝宝")
print(ret) # 范伟
View Code

 

1. 增加

dic = {}
dic['name'] = '周润发' # 如果dict中没有出现这个key, 就会新增一个key-value的组合进dict
dic['age'] = 18
print(dic)

# 如果dict中没有出现过这个key-value. 可以通过setdefault设置默认值 
dic.setdefault('李嘉诚') # 也可以往⾥面设置值.
dic.setdefault("李李嘉诚", "房地产") # 如果dict中已经存在了. 那么setdefault将不会起作⽤
print(dic)

 

2. 删除

ret = dic.pop("jay")
print(ret)

del dic["jay"]
print(dic)

# 随机删除.  Python老版本是随机删除,现在就是删除最后一项
ret = dic.popitem()

# 清空字典中的所有内容 
dic.clear()

 

3. 修改

dic = {"id": 123, "name": 'sylar', "age": 18}
dic1 = {"id": 456, "name": "麻花藤", "ok": "wtf"}
dic.update(dic1) # 把dic1中的内容更新到dic中. 如果key重名. 则修改替换. 如果不存在key, 则新增.
print(dic)
print(dic1)

 

4. 查询

查询一般是用key来查找具体的数据.

 print(dic['name'])
# print(dic['sylar']) # 报错 

print(dic.get("ok"))
print(dic.get("sylar")) # None 
print(dic.get("sylar", "牛B")) # 牛B
# 注意:get(key,value=None):key 不存在返回第二个参数,上面返回的None是默认的

 

5. 其他相关操作-字典的遍历

dic = {"赵四":"刘晓光", "刘能":"王晓利", "王木生":"范伟"}
# 直接for循环
for key in dic: # 直接循环字典拿到的是key, 有key直接拿value
    print(key)
    print(dic[key])

dic = {"赵四":"刘晓光", "刘能":"王晓利", "王木生":"范伟"}

# 不常用的
print(dic.keys()) # dict_keys(['赵四', '刘能', '王木生']) 像列表. 山寨列表
for k in dic.keys(): # 拿到的是字典中的每一个key
    print(k)

# 当需要单独获取到所有value的时候
print(dic.values()) # dict_values(['刘晓光', '王晓利', '范伟'])  所有的value的一个数据集
for v in dic.values():
    print(v)

print(dic.items()) # 所有的键值对 dict_items([('赵四', '刘晓光'), ('刘能', '王晓利'), ('王木生', '范伟')])
# 遍历字典最简单的方案
for item in dic.items(): # 遍历字典最简单的方案##这里涉及到一个自动解构的过程
    print(item) # ('赵四', '刘晓光')  
    k, v = item  # 解构,##item 是一个中间变量,可以直接省略掉
    k = item[0]  
    v = item[1]
    
for k, v in dic.items(): # 遍历字典最简单的方案##这里涉及到一个自动解构的过程
    # k, v = item # 解构,##item 是一个中间变量,可以直接省略掉
    print(k, v)


a, b = 1, 2  # 把后面的两个值分别赋值给前面两个变量. 解构, 解包
print(a)
print(b)


''' 老师课上讲解的总结:
------------------------------------------------------------------------
# a,b = 1,2 #解构必须前后数量相等,不等会报错
# a,b = (1,2)
# (a,b) = (1,2)#上面的三种写法是等价的,#元组的括号可以不加,只要有逗号就是元组类型的
# print(a)
# print(b)

#元组的括号可以不加,只要有逗号就是元组类型的
# a = 1
# print(type(a)) #<class 'int'>
# a = 1,
# print(type(a)) #<class 'tuple'>
# a = (1,)
# print(type(a))#<class 'tuple'>
-------------------------------------------------------------------------
'''
c = 1,2,3
print(c) # (1, 2, 3) # 元组和列表是可以解包的

d, e, f = [1,2,3]
print(d)
print(e)
print(f)


# 遍历字典两套方案(最常用的,需要记忆的)
dic = {"赵四":"刘晓光", "刘能":"王晓利", "王木生":"范伟"}
# 1. 使用for循环直接遍历字典的key
for key in dic:
    print(key)
    print(dic[key])

# 2. 可以使用字典的items()+解构可以直接获取到key和value
for k, v in dic.items():
    print(k)
    print(v)
View Code

 

dic = {"id": 123, "name": 'sylar', "age": 18, "ok": "科⽐"}

print(dic.keys()) # dict_keys(['id', 'name', 'age', 'ok']) 不用管它是什么.当 成list来用就行
for key in dic.keys():
    print(key)

print(dic.values()) # dict_values([123, 'sylar', 18, '科⽐']) 一样. 也当list来⽤
for value in dic.values():
    print(value)

print(dic.items()) # dict_items([('id', 123), ('name', 'sylar'), ('age', 18), ('ok', '科⽐比')]) 这个东西也是list. 只不过list中装的是tuple
for key, value in dic.items(): # ?? 这个是解构
    print(key, value)

# 解构
a, b = 1, 2 
print(a, b)

(c, d) = 3, 4
print(c, d)

e, f = [1, 2, 3]  # 解构的时候注意数量必须匹配,否则报错
print(e, f)

3. 字典的嵌套

wf = {
    "name":"汪峰",
    "age":52,
    "hobby":["唱歌", "上头条", "穿皮裤"],
    "wife": {
        "name": "章子怡",
        "age": 49,
        "hobby":["演戏", "上电视", "当导师"],
        "tishen": {
            "name":"萌萌",
            "age":28
        },
        "zhuli":{
           "name":"磊磊",
           "age": 20
        }
    },
    "zhuli":{
        "name":"宝宝",
        "age":23,
        "hobby":["抽烟","喝酒","烫头"]
    },
    "children":[{"name":"汪老大"}, {"name":"汪老二"}]
}
wf['children'][1]["age"] = 2
print(wf)
# print(wf['zhuli']['name'])

# 汪峰老婆替身的名字
print(wf['wife']['tishen']['name'])
# 汪峰老婆的第二个爱好
print(wf['wife']['hobby'][1])
# 汪峰助理的第三个爱好
print(wf['zhuli']['hobby'][2])


# 汪峰的助理+10岁
wf['zhuli']['age'] = wf['zhuli']['age'] + 10
# 汪峰的老婆添加一个爱好("导戏")
wf['wife']['hobby'].append("导戏") # 添加完毕了
# 删除汪峰助理的"抽烟"爱好
wf["zhuli"]["hobby"].remove("抽烟")
print(wf)
View Code

 

# 字典的嵌套 
dic1 = {
    "name": "汪峰", 
    "age": 18, 
    "wife": {
        "name": '章子怡',
        "age": 28 
    },
    "children": ['第一个毛孩子', '第二个毛孩子'],
    "desc": '峰哥不会告我吧. 没关系. 我想上头条的' 
}

print(dic1.get("wife").get("name"))
print(dic1.get("children"))
print(dic1.get("children")[1])
 

set集合

s = {"周润发", "大润发", "王润发", "周润发"} # 不重复的
print(s)

# 唯一能用到的点. 去重复(使用强制类型转化的办法:列表-->集合(去除重复的元素)-->列表)
lst = ["麻将", "牌九", "骰子", "扑克", "老虎鸡", "骰子", "扑克", "老虎鸡", "扑克", "老虎鸡", "扑克", "老虎鸡"]

# 把列表转化成集合  x 转化成y类型 y()
s = set(lst)
# print(s)
# 把集合变回列表
lst = list(s)
print(lst) # 顺序是乱的(唯一的缺点,但是功(去重复)大于过.排序和去重复都是相当麻烦的一件事)

#
s = {"刘嘉玲", "赵本山", "莱昂纳多迪卡普里奥", "罗纳尔多"}
s.add("刘嘉玲") # 记忆(如果实在是想要记忆的话)
print(s)

s.update({"刘嘉玲", "刘能", "赵四"}) # 迭代更新
print(s)


#
ret = s.pop() # 随机删除(弹出)一个,类似于字典的popitem()
print(s)
print(ret)

s.remove("罗纳尔多")
print(s)

# 注意:集合还有字典. 是没有索引和切片的

#
#set集合中的数据没有索引,也没有办法去定位一个元素,所以没有办法进行直接修改.我们可以采用先删除后添加的方式来完成修改的操作
s = {"刘嘉玲", "赵本山", "莱昂纳多迪卡普里奥", "罗纳尔多"}
# 把罗纳尔多修改成梅西
s.remove("罗纳尔多")#先删除
s.add("梅西")#后修改
print(s)


#查询
# 迭代
for el in s:
    print(el)

#下面是一些不常使用的操作
s1 = {"门神", "灯神", "灯神你在笑什么?"}
s2 = {"门神", "灯神", "你俩在干什么?"}

# 交集
print(s1 & s2)
print(s1.intersection(s2))

# 并集
print(s1 | s2)
print(s1.union(s2))

# 差集
print(s1 - s2) # s1中特有的内容
print(s1.difference(s2))

# 反交集
s1={1,2,3,44}
s2={1,2,3,55}
print(s1 ^ s2) # 两个集合中特有的内容  {55, 44}
print(s1.symmetric_difference(s2))

# 集合本身是可变的数据类型 . 不可哈希
# 集合套集合->不能互相嵌套的
# 集合中的元素必须可哈希(不可变的)
s = {{1,2,3}}  # TypeError: unhashable type: 'set'
print(s)
# # 如果非要集合套集合 下面是不可变集合
s = frozenset({"哈哈","呵呵"}) # 不可变的数据类型(集合)
for el in s:
    print(el)
s = {s}
print(frozenset({"哈哈","呵呵"}))
View Code

set集合是python的一个基本数据类型. 一般不是很常用. set中的元素是不重复的.无序的.⾥面的元素必须是可hash的(int, str, tuple,bool), 我们可以这样来记. set就是dict类型的数据但是不保存value, 只保存key. set也用{}表示

 

注意:set集合中的元素必须是可hash的(不可变),但是set本身是不可hash的(可变的).

set1 = {'1', 'alex',2,True,[1,2,3]} #报错
set2 = {'1', 'alex' ,2,True,{1:2}} # 报错
set3 = {'1', 'alex' ,2,True,(1,2,[2,3,4])}#报错

 

set中的元素是不重复的,且无序的.
s = {"周杰伦""周杰伦",”周星星"}
print(s)
结果:
{'周星星'' 周杰伦'}

 

使用这个特性,我们可以使用set来去掉重复
#给list去重复
lst = [45,5,"哈哈",45,"哈哈",50]
lst = list(set(lst))#把list转换成set, 然后再转换回list
print(lst)

 

set集合增删改查

1.增加

s = {"刘嘉玲"'关之琳'"王祖贤"}
s. add( "郑裕玲")
print(s)
s. add("郑裕玲")#重复的内容不会被添加到set集合中
print(s)

s = {"刘嘉玲"'关之琳'"王祖贤"}
s. update("麻花藤")#迭代更新
print(s)
s. update(["张曼玉”," 李若彤" ,"李若彤"])
print(s)

 

2. 删除

s = {"刘嘉玲", '关之琳', "王祖贤","张曼玉", "李若彤"} 
item = s.pop() # 随机弹出一个.
print(s)
print(item)

s.remove("关之琳") # 直接删除元素
# s.remove("⻢虎疼") # 不存在这个元素. 删除会报错 
print(s)

s.clear() # 清空set集合.需要注意的是set集合如果是空的. 打印出来是set() 因为要和 dict区分的.
print(s) # set()

 

3. 修改

 # set集合中的数据没有索引. 也没有办法去定位⼀一个元素. 所以没有办法进⾏直接修改. 
# 我们可以采⽤先删除后添加的方式来完成修改操作
s = {"刘嘉玲", '关之琳', "王祖贤","张曼玉", "李若彤"}
# 把刘嘉玲改成赵本⼭
s.remove("刘嘉玲") 
s.add("赵本⼭山") 
print(s)

 

4. 查询

# set是一个可迭代对象. 所以可以进⾏for循环 
for el in s:
    print(el)

 

5. 常用操作

s1 = {"刘能", "赵四", "⽪长山"}
s2 = {"刘科⻓", "冯乡长", "⽪长山"}

# 交集
# 两个集合中的共有元素
print(s1 & s2) # {'⽪长山'} print(s1.intersection(s2)) # {'⽪长山'}

# 并集
print(s1 | s2) # {'刘科长', '冯乡长', '赵四', '⽪长山', '刘能'} 
print(s1.union(s2)) # {'刘科长', '冯乡长', '赵四', '⽪长山', '刘能'}

# 差集
print(s1 - s2) # {'赵四', '刘能'} 得到第一个中单独存在的 
print(s1.difference(s2)) # {'赵四', '刘能'}

# 反交集
print(s1 ^ s2) # 两个集合中单独存在的数据 {'冯乡长', '刘能', '刘科长', '赵四'} print(s1.symmetric_difference(s2)) # {'冯乡长', '刘能', '刘科长', '赵四'}



s1 = {"刘能", "赵四"}
s2 = {"刘能", "赵四", "⽪长山"}

# 子集
print(s1 < s2) # set1是set2的子集吗? True print(s1.issubset(s2))

# 超集
print(s1 > s2) # set1是set2的超集吗? False print(s1.issuperset(s2))

 

set集合本身是可以发生改变的. 是不可hash的. 我们可以使用frozenset来保存数据. frozenset是不可变的. 也就是一个可哈希的数据类型

s = frozenset(["赵本山", "刘能", "⽪长山", "长跪"])
dic = {s:'123'} # 可以正常使用了 
print(dic)

这个不是很常用. 了解一下就可以了

 

 

 

 

 

今日作业

今日作业

posted on 2019-06-24 14:21  Lyf凤  阅读(279)  评论(0编辑  收藏  举报

导航

levels of contents