python学习之数据类型—字典dict
字典:dict
1、字典是python中唯一的一个映射类型,以{}括起来的价值对组成;
2、字典中key是唯一的,在保存的时候,根据key来计算出一个内存地址,如何将value放在这个内存中,这种称为hash算法;
3、字典中的key必须是可hash的即(不可变的数据类型str,int,tuple,bool)
4、字典中的value可以存任意数据类型
5、字典也是无序的,故没有通过索引找值一说,只能通过key找value
6、字典中的key如果出现相同的,后面加入的会将前面的value值覆盖
语法:
dict = {key:value,……}
增:
1、直接添加
dic ["BeiJing"] = "政治中心"
注:如果字典中无”BeiJing“这个key,则新增,如有则改变对应的value值为新值
2、setdefault(key,value)方法添加,value可不写,默认为none
dic .setdefault("china") ---> {"china":None}
dic .setdefault("china","中国") --->{"china":None},一旦通过setdefault方法添加了key,之后就无法改变改key对应的值
1 li = [11, 22, 33, 44, 55, 66, 77, 88, 99, 90] 2 dic = {} 3 for i in li: 4 if i > 66: 5 dic.setdefault("k1",[]).append(i) 6 else: 7 dic.setdefault("k2",[]).append(i)
setdefault可以同时创建key及value,在开始时创建字典时不指定key和value
删:
1、指定key值来删除
ret = dict.pop(key) 有返回值,返回的是删除的值,同list 一样,str与tuple是不可变数据类型故无pop方法
del dict 删除字典对象
del dict[key] 按key来删除,无返回值,为None
2、随机删除dict.popitem()
ret = dict.popitem() #随机删除字典中的元素,返回一个包含键值对的tuple (key,value)
解构:
k,v = dict.popitem()
print(k,v)
3、清空字典
dict.clear()
改:
1、直接通过key赋予新值
dict[key] = new_value
2、两个字典合并成一个 dict_to.update(dict_from)
dict3 = {"name": "sun", "age": 30}
dict4 = {"name": "xiu", "age": 30, "hobby": "play_tv"}
dict3.update(dict4) # 将dict4更新到dict3中,如果dict3中key存在,对应value值将覆盖,如果不存在,则新增
查:
1、通过key查value
dict[key] 如key不存在,则报错
dict.get(key,自定义返回值) 如key不存在,默认返回None,也可自定义
2、查询字典中所有的keys dict_keys(['name', 'age', 'hobby'])
for i in dict.keys():
print(i)
3、查询字典中所有的values dict_values(['xiu', 30, 'play_tv'])
for i in dict.values():
print(i)
4、查询字典中所有的元素items dict_items([('name', 'xiu'), ('age', 30), ('hobby', 'play_tv')])
for i in dict.items():
print(i) #i 是一个元组
如果要对dic.keys()等操作一定要先转换成列表:
字典补充:
增 dict.fromkeys(iterable,value)
将前面可迭代的对象中的元素分别为字典的key,每个key的value都为后面设置的值,且如其值为可变数据类型,都指向同一内存地址,即改了任意key的值,其他都会更新
1 # 当其值value不为列表或字典时,可正常修改,不会产生连带效果
2 dic = dict.fromkeys("abc", "old_boy") # {'a': 'old_boy', 'b': 'old_boy', 'c': 'old_boy'}
3 dic["a"] = "keep" # {'a': 'keep', 'b': 'old_boy', 'c': 'old_boy'}
4 # 如果dic的value也是iterable如是列表或是字典,当向其中某一key对应的列表中添加值时,其他都会同时添加
5 # 说明他们都指向同一个列表内存地址
6 dic1 = dict.fromkeys("ab", []) # {'a': [], 'b': []}
7 dic1["a"].append("test") # {'a': ['test'], 'b': ['test']}
8
9 dic2 = dict.fromkeys("ab", {"key_test":"ddd"}) # {'a': {'key_test': 'ddd'}, 'b': {'key_test': 'ddd'}}
10 dic2["a"]["key_test"] = "important" # {'a': {'key_test': 'important'}, 'b': {'key_test': 'important'}}
fromkeys是类dict的静态方法
dic = {}
dic.fromkeys(["学习",“学历”],[2018,2010])
print(dic) ----> 还是为{},dic没有接受内容
字典删除问题:(类似于循环迭代删除列表元素时,索引在变化,从而报错或删除不全)
因为字典是不可哈希即可变数据类型,其key是可hash的数据类型,且字典又是无序的,(可能建立迭代时在内存中是一整块,?)
而for循环迭代字典得到的是类似装着所有key的列表,因此在删除时,会报错说在迭代时改变了字典的大小。
字典不允许在循环迭代时删除键。
1 dic = {"name": "sun", "age": 30, "hobby": "make_money"}
2 for i in dic:
3 dic.pop(i) # RuntimeError: dictionary changed size during iteration(在遍历循环时改变了字典的长度)
删除字典或时列表中某些键值对或元素时,可以先将其要删除的元素保存到一个列表中,然后遍历那个遍历那个列表(通过元素找),
在字典或原列表中删除指定元素,这样就避开了,直接删索引在变化的僵局。
1 # 计划删除age键值对
2 # 创建计划删除元素或key的空列表
3 del_el_lsit = []
4 # 遍历字典将要删除的键放到del_el_list列表中
5 for i in dic:
6 if i == "age":
7 del_el_lsit.append(i)
8 print(del_el_lsit) # ['age']
9 # 以计划删除元素存放的列表为参照物,遍历列表拿到计划到字典中预删key值,通过找key的方式删字典中键值对
10 for i in del_el_lsit:
11 del dic[i]
12 print(dic) # {'name': 'sun', 'hobby': 'make_money'}
学习中发现得小问题:
print({True: "3333", 1: 99999, "name": 333, 1: 77777, "ddd": 3333, 1: 0000})
# {True: 0, 'name': 333, 'ddd': 3333}
# 从左到右,如果一个字典中的键是bool值或1,如True或1后面还有1或True为键的,最后会将True或1的value更新为最后键为的值
# 即谁先出现,就更新谁得value