前言:
之前博客說過,一個字典是否包含在另一個字典中,可以將字典轉化為set,然后使用他其中的issubset來判斷是否存在包含關系。詳細可參考:https://www.cnblogs.com/dflblog/p/11944980.html
也就是已知一個dict,比如為a = {"a":1},另一個dict比如為b = {"a":1,"b":2},想要一個結果判斷a是否在與b中,將a轉化為set,b轉化為set,然后用a的issubset來確認是否返回Ture。
背景:
這里會存在一個問題,因為set是一個無序且不重復的元素集合。元素為不可變對象!!!
是什么意思,也就是如上例,b的數據類型為這個樣子的話:
b = {"a":{"aa":11},"b":[1,2,3],"c":(1,2,3)}
那么就直接異常了。
代碼先跑起來:
d = {"a":{"aa":11},"b":[1,2,3],"c":(1,2,3)} dd = set(d.items())
結果直接拋出異常TypeError: unhashable type: 'dict'。
告訴我們類型錯了,dict是一個可變對象,說到這里又開始上篇的問題了。如果都是不可變對象,上篇是可以使用的
但如果存在可變對象,沒辦法轉化成set類型, 這個怎么處理???
沒辦法,只能自己一個一個處理了。給打開放一個剛設計的一個例子。
仔細看的人會發現還有問題存在~~嘻嘻嘻。
a = {"a":{"aa":11}} a1 = {"d":"d"} b = {"a":{"aa":11},"b":[1,2,3],"c":(1,2,3)} class assertDictIn: def __init__(self): ## 初始化set類型 self.result = set() def _getKeys(self,data): ## 等於dict類型 if type(data) == dict: ## 循環走起 for key,value in data.items(): ## 若循環的value值為list類型,繼續調用 ## 各個為空處理 if type(value) == list: if value == []: self.result.add(key) self.result.add(value) else: self._getKeys(value) if type(value) == dict: ## 如果dict為空處理 if value == {}: self.result.add(key) self.result.add(value) else: self._getKeys(value) ## 同list if type(value) == tuple: if value == (): self.result.add(key) self.result.add(value) else: self._getKeys(value) self._getKeys(value) ## 如果循環的value類型為基本類型,直接添加 if type(value) in (str,int,float,set): self.result.add(key) self.result.add(value) ## 若傳入類型為list或者tuple if type(data) in (list,tuple): ## 依舊循環走起 for value in data: ## list時繼續調用 if type(value) == list: self._getKeys(value) ## dict時也繼續調用 if type(value) == dict: self._getKeys(value) ## tuple時繼續調用 if type(value) == tuple: self._getKeys(value) ## 若為這些類型,直接添加 if type(value) in (str, int, float, set): self.result.add(value) ## 若傳入為set類型,直接添加 if type(data) is set: for value in data: self.result.add(value) return self.result def checkIn(self,first:dict,second:dict): ## 非字典處理,直接raise if type(first) != dict or type(second) != dict: raise Exception("內部目前僅支持dict類型判斷") ## 賦值第一個參數 fir = self._getKeys(first) ## 重置一下結果 self._clear() ## 賦值第一個參數 sec = self._getKeys(second) ## 也重置一下吧 self._clear() ## 斷言 if fir.issubset(sec): return True else: return False def _clear(self): self.result = set() asser = assertDictIn() print(asser.checkIn(a,b)) print(asser.checkIn(a1,b))
結果為:
Ture
False