深入 Dict set一些代碼的例子

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的存儲順序和元素添加的順序有關
添加數據有可能改變已有數據的順序

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章