概念相关

概述: 
字典是以 key - value(键值对)的形式来存储数据的,查找速度快
key的特点:
	1.key是唯一的
	2.key 必须是是不可变类型(可哈希的)
	3.无序的
	4.可变类型: 列表,字典 #主要看内存,可变不会新开辟内存地址,即是在原有的地址上面改变值,所以是可变的
	5.不可变类型:如 数字,字符串,... #不可变,会新开辟地址,因为原有的地址不可再改变值,所以是不可变的
	
格式: {key1:value1,key2:value2, ... }
描述: 字典的 key与value是以 :(冒号) 连接,key与value组成字典的一个元素,元素与元素
用 ,(逗号)连接 ,字典使用 { } 包裹起来的
已知的可哈希(不可变)的数据类型: int, str, tuple, bool
不可哈希(可变)的数据类型: list, dict, set
创建
# 创建一个空字典
dict1 = {}
# print(dict1)
# print(type(dict1))

创建一个有多个值字典
dict2 = {"name1":"李钟硕","name2":"刘德华","name3":"吴彦祖","name4":"三胖胖"}

# key不能重复,只会保留一个key对应的值,后面的会覆盖前面的
dict2 = {"name1":"小贱贱","name1":"刘德华","name3":"吴彦祖","name4":"三胖胖"}
#注意: 字典的key需要不可变的类型
#错误:dict2 = {"name1":"小贱贱",[1,2,3]:"刘德华","name3":"吴彦祖","name4":"三胖胖"}

#字典是无序的,数据量大的时候,输出不一定是这种顺序结果
print(dict2)

增删改(查)

查:
dict2 = {"name1":"李钟硕","name2":"刘德华","name3":"吴彦祖","name4":"三胖胖"}

#注意: 字典是无序的,不可以用索引来获取值
# name = dict2[2](不可用)

# 字典通过key来获取值value
# 格式: 字典名[key]
name = dict2["name4"]
#注意: 当key不存在的时候,会抛出异常,使程序崩溃
name = dict2["age"]

# 使用get方式获取值,当key不存在时, 不会抛出异常,返回None
# 参数2,用来设置默认值,当key不存在时,就返回该默认值
name = dict2.get("age") #None
name = dict2.get("gender","男") #设置默认值
print(name)

.setdefault(key)可以查,不过是已有的元素,没有的返回None;
# 它的本质是先找一遍,有不添加,没有添加

#注意:len(dict)结果是测量,键值对的个数
增:
dict3 = {"name1":"小贱贱","name2":"刘德华","name3":"吴彦祖","name4":"三胖胖"}
dict3["name5"] = "李小璐"

dict3.setdefault(key,value)  #.setdefault()后面直接加键值对
# setdefault 如果dict中没有出现过这个key-value. 就会添加;如果有不进行任何操作,
# 可以通过setdefault设置默认值
改
dict3 = {"name1":"小贱贱","name2":"刘德华","name3":"吴彦祖","name4":"三胖胖"}
dict3["name2"] = "文章"
# print(dict3)

# 注意: 
# 格式: 字典名[key] = 值
# 注意: 如果 key 已经存在,则表示的是修改key对应的value值
# 如果key不存在, 则表示的是向该字典中添加一个新的键值对

#第二种:.update()
dic = {"id": 123, "name": 'sylar', "age": 18}
dic1 = {"id": 456, "name": "麻花藤", "ok": "wtf"}
dic.update(dic1) 
# 把dic1中的内容更新到dic中. 如果key重名. 则修改替换. 如果不存在key, 则新增
print(dic)
print(dic1)
删:
# 第一种:.pop()删除
# 根据key来删除一个值,会返回删除的值,如果key不存在,且没有设置default(默认,缺省)值,会抛异常
# 如果设置了,则会返回默认值
name = dict3.pop("name8","哈哈哈")
# 先判断key是否存在,再进行数据操作
if "name2" in dict3:
     print("存在")
else:
     print("不存在")
print(name)

# 第二种:del dict[key] 通过key 来删除
dict2 = {"name1":"刘德华","name3":"吴彦祖","name4":"三胖胖"}
del dict2["name1"]
print(dict2)

# 第三种:dict.clear()
dict2.clear()

# 第四种:dict.popitem() 删除最后一组键值对 返回值 是一个元组 (key,value)

locals = {"鲁": "山东", "沪": '上海', "黑": '黑龙江'}

# 用来从后往前删,留下想要的内容
while True:
     locals.popitem()
     if len(locals)==1:
         break
print(locals)


# 删除全部元素(清空字典)
dic = {"提莫":"冯提莫", "发姐":"陈一发儿", "55开":"卢本伟"}
new=[]
for key in dic: #key
#dic.pop(key) 错误,不能直接这样删,字典在循环过程中不能改变长度(不能删除和添加元素)
    new.append(key)
for el in new:
    dic.pop(el)
print(dic)

字典的常见操作

6种遍历方式
dict4 = {"name1":"小贱贱","name2":"刘德华","name3":"吴彦祖","name4":"三胖胖"}

# 遍历字典,可以获取到每一个key,

# 第一种:
for key in dict4: #拿到的是全部的key
     #print(key)
     print("key=%s ,value=%s"%(key,dict4[key]))

for i in range(len(dict4)): #打印字典的索引
     print(i)

# 第二种:
for index,key in enumerate(dict4):
     #print(index)
     #print(key)
     print("key=%s ,value=%s"%(key,dict4[key]))


# 第三种:
keys = dict4.keys()
     print(keys)
     #keys是获取所有元素的key值
for key in dict4.keys():
     print("key=%s ,value=%s"%(key,dict4[key]))

# 第四种:
#values 是获取所有元素的value值
for value in dict4.values():
     print(value)

# 第五种:
#items是获取所有的 key-value键值对
for key,value in dict4.items():
     print("key=%s ,value=%s"%(key,value))

for i in dict1.items():
     key,values=i #解包
     print(key,values)

# 第六种:
#通过set来
dic = {"提莫":"冯提莫", "发姐":"陈一发", "55开":"卢本伟"}
key=set(dic) #set后会取出所有key,但是类型是set
list_key=list(key)
#print(key) {"提莫","发姐","55开"}
#print(type(key)) calss"set"
for el in list_key:
     print(el,dic[el])

【补充】
解构(解包):
#支持: 字符串 元组 列表

a, b = 1, 2
print(a, b) # 1 2
(c, d) = 3, 4
print(c, d) #3 4

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

字典的其他操作

.fromkeys(可迭代对象,值),用于批量创建,但是value都会相同
dict2={}
new=dict2.fromkeys([1,2,3],[1,[2]])
print(new)
#{1: [1, [2]], 2: [1, [2]], 3: [1, [2]]}

#fromkeys直接使用类名进行访问,共用第二个参数(值)

字典的嵌套:
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])
与list比较
# dict字典:字典查找,插入的速度极快, 随着数据量的增加,对速度没有太大影响
# 字典需要的内存较大,消耗内存

# list列表: 列表查找,插入速度较慢, 随着数据量的增加,对速度影响较大
# 列表需要的内存较小,节约内存

copy操作,复制:
# dict5 = {"name1":"小贱贱","name2":"刘德华","name3":"吴彦祖","name4":"三胖胖"}
# print(dict5)
# dict6 = dict5
# dict6["name1"] = "美味可口的小贱贱"
# print(dict6)
# print(dict5)

dict7 = {"name1":"小贱贱","name2":"刘德华","name3":"吴彦祖","name4":"三胖胖"}
print(dict7)
dict8 = dict7.copy()
dict8["name1"] = "美味可口的小贱贱"
print(dict8)
print(dict7)

练习题

>>>
dict1 = {
     'name':['alex',2,3,5],
     'job':'teacher',
     'oldboy':{'alex':['python1','python2',100]}
     }

'''
1,将name对应的列表追加一个元素’wusir’。
2,将name对应的列表中的alex首字母大写。
3,oldboy对应的字典加一个键值对’老男孩’,’linux’。
4,将oldboy对应的字典中的alex对应的列表中的python2删除。

'''
dict1.get("name").append("wusir")
print(dict1)

dict1.get("name")[0]=dict1.get("name")[0].capitalize()
print(dict1)

dict1.get("oldboy").setdefault("老男孩","linux")
print(dict1)

dict1.get("oldboy").get("alex").pop(1)
print(dict1)


>>>将字符串"k1:1|k1:2|k2:3|k3:4",编程字典{k1:1,k1:2...}
str="k1:1|k1:2|k2:3|k3:4"
list_str=str.split("|")
key=[]
value=[]
#for re in list_str:
for re in list_str:
key.append(re.split(":")[0])
value.append(re.split(":")[1])

dic={}
# 字典新增元素
for n in range(len(key)):
     dic[key[n]]=value[n]


for n in range(len(key)):
dic.setdefault(key[n],value[n])
print(dic)

# 方法二:用到“解包”
str="k1:1|k1:2|k2:3|k3:4"
list_str=str.split("|")
dic={}
for c in list_str:
     key,value=c.split(":") #解包,注意分割后都是字符串类型
     dic[key]=int(value)
     #dic.setdefault(key,value)
print(dic)


>>>将小于66的放在第一个空列表,将大于66的放在第二个空列表
li= [11,22,33,44,55,66,77,88,99,90]
dic={"k1":[],"k2":[]}
for i in li:
     if i == 66:continue
     elif i >66:
         dic.setdefault("k1").append(i)#通过k1找到的是“[]”
         #setdefault会先根据key去字典查找,如果能找到键则不新增
     else:
         dic.setdefault("k2").append(i)
print(dic)


>>>
'''
1:页面显示 序号 + 商品名称 + 商品价格,如:
1 电脑 1999
2 鼠标 10
…
2:用户输入选择的商品序号,然后打印商品名称及商品价格
3:如果用户输入的商品序号有误,则提示输入有误,并重新输入。
4:用户输入Q或者q,退出程序。
'''
goods = [{"name": "电脑", "price": 1999},
     {"name": "鼠标", "price": 10},
     {"name": "游艇", "price": 20},
     {"name": "美女", "price": 998}, ]

while True:
     for dic in goods:
         print(goods.index(dic)+1,dic["name"],dic["price"])

     str_input = input('请输入您要选着的商品序号,输入Q/q退出:')
     if str_input.isdigit() and 0 < int(str_input) <= len(goods):
         print(goods[int(str_input)-1]["name"],goods[int(str_input)-1]["price"])
     elif str_input.upper() == 'Q':
         break
     else:
         print('输入有误,请重新输入!')

>>>用户输入数字相加,求和,并将他们放入到字典中

dic={}
content=input("please enter you need sum number:")
content.replace(" ","").strip()
lis_num=content.split("+")
sum=0
for el in lis_num:
     sum+=int(el)
dic["total"]=sum
print(dic)

>>>
'''
让用户随机输入10个数,
将这10个数保存在列表中,
将所有大于 55 的值保存至字典的第一个key的值中,
将小于 55 的值保存至第二个key的值中。
'''
lst = []
for i in range(10):
     c = input("请输入一个数:")
     lst.append(int(c))

key1 = []
key2 = []
for el in lst:
     if el > 55:
          key1.append(el)
     elif el < 55:
          key2.append(el)
dic = {"key1":key1, "key2":key2}
print(dic)


>>>车牌区域划分,给出以下车牌和地点信息对照,请根据车牌信息,分析出各省的车牌持有数量。
cars = ['鲁A32444', '鲁B12333', '京B8989M', '黑C49678', '黑C46555', '沪B25041', '黑C34567']
locations = {'沪': '上海', '京': '北京', '黑': '黑龙江', '鲁': '山东', '鄂': '湖北', '湘': '湖南'}

res={}
for car in cars:
     location=locations[car[0]]
     if res.get(location)==None:
          res[location]=1
     else:
          res[location]+=1
print(res)

#优化
result = {}
for car in cars: # car是车牌子
     result[locations[car[0]]] = result.get(locations[car[0]], 0) + 1
print(result)


>>>将列表 li 中,大于66的添加到字典的key1中,小于66的添加到字典的key2中

li=[11,22,33,44,55,77,88,99,90]
dic={}
for el in li:
     if el>66:
          if "key1" not in dic:#这个if只需要走一次即可
               dic["key1"]=[]
          dic["key1"].append(el)
     else:
          if "key2" not in dic:
               dic["key2"] =[]
          dic["key2"].append(el)
print(dic)


【深入题】
>>>将list3动态变成list4格式
list3 = [
     {"name": "alex", "hobby": "抽烟"},
     {"name": "alex", "hobby": "喝酒"},
     {"name": "alex", "hobby": "烫头"},
     {"name": "alex", "hobby": "Massage"},
     {"name": "wusir", "hobby": "喊麦"}, #第五次
     {"name": "wusir", "hobby": "街舞"},
     {"name": "taibai", "hobby": "开车"},
     {"name": "taibai", "hobby": "嫂子"},
     ]
#list4 = [
#     {"name": "alex", "hobby_list": ["抽烟", "喝酒", "烫头", "Massage"]},
#     {"name": "wusir", "hobby_list": ["喊麦", "街舞"]},
#]

list4= [] 
for ren in list3: #第一次:{"name": "alex", "hobby": "抽烟"} 第二次:{"name": "alex", "hobby": "喝酒"}第三次:{"name": "alex", "hobby": "烫头"},
     for el in list4: #第一次:空,第二次 el {"name": "alex", "hobby_list": ["抽烟"]},第三次:el {"name": "alex", "hobby_list": ["抽烟","喝酒"]}
          if el['name'] == ren['name']:
               el['hobby_list'].append(ren['hobby'])
               break
     else:
          dic = {}
          dic['name'] = ren['name']
          dic['hobby_list'] = [ren['hobby']]
          list4.append(dic) #第一个人进去;第五次循环时,再添加人了
print(list4)