dict常見方法
mapping協議
from collections.abc import Mapping,MutableMapping
#dict屬於Mapping類型
dict1={}
print(isinstance(dict1,MutableMapping))
print(isinstance(dict1,Mapping))
a={"xiaopang1":{"A":1,"B":2,"C":6},"xiaopang2":{"C":23,"D":"eater","E":"music"}}
a.clear()
print(a)#清空字典中的元素
import copy
# copy 返回的是一個淺拷貝
a={"xiaopang1":{"A":1,"B":2,"C":6},"xiaopang2":{"C":23,"D":"eater","E":"music"}}
new_dict=a.copy()
new_dict["xiaopang1"]["A"]="xiaohe"
print(new_dict)
#{'xiaopang1': {'A': 'xiaohe', 'B': 2, 'C': 6}, 'xiaopang2': {'C': 23, 'D': 'eater', 'E': 'music'}}
print(a)
#{'xiaopang1': {'A': 'xiaohe', 'B': 2, 'C': 6}, 'xiaopang2': {'C': 23, 'D': 'eater', 'E': 'music'}}
a={"xiaopang1":{"A":1,"B":2,"C":6},"xiaopang2":{"C":23,"D":"eater","E":"music"}}
print("....................................................")
new_dict=copy.deepcopy(a)
new_dict["xiaopang1"]["A"]="xiaohe"
print(new_dict)
#{'xiaopang1': {'A': 'xiaohe', 'B': 2, 'C': 6}, 'xiaopang2': {'C': 23, 'D': 'eater', 'E': 'music'}}
print(a)
#{'xiaopang1': {'A': 1, 'B': 2, 'C': 6}, 'xiaopang2': {'C': 23, 'D': 'eater', 'E': 'music'}}
print("................................................")
#fromkeys
new_list=["xiaopang","xiaohe"]
#其實相當於可以爲字典放置一個任意類型的值
new_dictx=dict.fromkeys(new_list,{"company":"imooc"})
#{'xiaopang1': {'A': 1, 'B': 2, 'C': 6}, 'xiaopang2': {'C': 23, 'D': 'eater', 'E': 'music'}}
new_dictx=dict.fromkeys(new_list,[i for i in range(2)])
new_dictx=dict.fromkeys(new_list,(1,2,3))
#{'xiaopang': (1, 2, 3), 'xiaohe': (1, 2, 3)}
new_dictx=dict.fromkeys(new_list,"")
{'xiaopang': '', 'xiaohe': ''}
new_dictx=dict.fromkeys(new_list,1)
new_dictx=dict.fromkeys(new_list,list)
#{'xiaopang': <class 'list'>, 'xiaohe': <class 'list'>}
print(new_dictx)
#get方法:是如果沒有這個值的話,不會報錯KeyError,而是接受一個指定返回值
#print(new_dictx["xiaohe1"])#KeyError: 'xiaohe1'
print(new_dictx.get("xiaohe1",{}))
print(new_dictx.get("xiaohe1","sss"))
for key,value in new_dictx.items():
print(key,value)
#setdefault()
defaultvalue=new_dictx.setdefault("libai","poet")
print(new_dictx)
#update() 參數爲可迭代對象
new_dictx.update({"x":"y"})
new_dictx.update(x1="y")
pass
#python 內置的一個子類
from collections import defaultdict
my_dict=defaultdict(dict)
myvalue=my_dict[“key”]
pass
set 、 frozenset
#set 集合frozenset(不可變集合)無序,不重複
# s=set('abcdee')
# print(s)
# s=set(['a','b','c','d','e'])
# s.add('x')
# s=frozenset("abcde") #frozenset可以作爲dict的key
# print(s)
#向set添加數據
s=set(['a','b','c','d','e'])
another_set=set(("x","c","v","v","v","v","b"))
s.update(another_set)
#s ={ 'a','e','x','d','v','b','c'}
#another_set{'v','b','x','c'}
# result1和result2等價
result1=s.difference(another_set)
result2=s-another_set
print(result2)
result3=s&another_set #取並集
result4=s|another_set #取交集
'''
其中包含了一些數學運算的魔法函數,需要自己查看python set源代碼
'''
print(s.issubset(result3))#False
print(result3.issubset(s)) #True
pass
dict set的實現原理
from random import randint
def load_list_data(total_nums, target_nums):
"""
從文件中讀取數據,以list的方式返回
:param total_nums: 讀取的數量
:param target_nums: 需要查詢的數據的數量
"""
all_data = []
target_data = []
file_name = "i://learning.txt"
with open(file_name, encoding="utf-8", mode="r") as f_open:
for count, line in enumerate(f_open):
if count < total_nums:
all_data.append(line)
else:
break
for x in range(target_nums):
random_index = randint(0, total_nums)
if all_data[random_index] not in target_data:
target_data.append(all_data[random_index])
if len(target_data) == target_nums:
break
return all_data, target_data
def load_dict_data(total_nums, target_nums):
"""
從文件中讀取數據,以dict的方式返回
:param total_nums: 讀取的數量
:param target_nums: 需要查詢的數據的數量
"""
all_data = {}
target_data = []
file_name = "i://learning.txt"
with open(file_name, encoding="utf8", mode="r") as f_open:
for count, line in enumerate(f_open):
if count < total_nums:
all_data[line] = 0
else:
break
all_data_list = list(all_data)
for x in range(target_nums):
random_index = randint(0, total_nums-1)
if all_data_list[random_index] not in target_data:
target_data.append(all_data_list[random_index])
if len(target_data) == target_nums:
break
return all_data, target_data
def find_test(all_data, target_data):
#測試運行時間
test_times = 100000
total_times = 0
import time
for i in range(test_times):
find = 0
start_time = time.time()
for data in target_data:
if data in all_data:
find += 1
last_time = time.time() - start_time
total_times += last_time
return total_times/test_times
#測試list和dict的性能
if __name__ == "__main__":
# all_data, target_data = load_list_data(23, 10)
# all_data, target_data = load_list_data(100000, 1000)
# all_data, target_data = load_list_data(1000000, 1000)
all_data, target_data = load_dict_data(23, 10)
# all_data, target_data = load_dict_data(100000, 1000)
# all_data, target_data = load_dict_data(1000000, 1000)
last_time = find_test(all_data, target_data)
print(last_time)
#dict 查找的性能遠遠大於list
#在list中隨着list數據的增大 查找時間會增大
#在dict中查找元素不會隨着dict的增大而增大
#5.530319213867188e-06 list
#1.1400651931762696e-06 dict
dict的key或者set的值 都必須是可hash的
不可變對象都是可hash的, str, frozenset,tuple,自己實現的類 hash
dict的內存花銷大,但是查詢速度快,自定義的對象 或者python內部的對象都是用dict包裝的。
dict的存儲順序和元素添加的順序有關
添加數據有可能改變已有數據的順序