返回信息流一道面试题,大致意思是实现一个dict,可能存在字典嵌套,用‘/’表示层级,其余和传统dict一致。例:
dict_1{‘a’:{‘b’:1, ‘c’:2}}
Input : dict_1[‘a/b’]
Output: 1
Input:dict[‘e/f/g’]=2
dict_1 {‘a’:{‘b’:1, ‘c’:2}, ‘e’:{‘f’:{‘g’:2}}}
昨天写了很久没写出来,想请教一下
这是一条镜像帖。来源:北邮人论坛 / python / #26174同步于 2022/8/20
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Python机器人发帖
Python内置dict如何实现
Xudongyu
2022/8/20镜像同步8 回复
订阅后,新回复会通过你的通知中心匿名送达。
8 条回复
```
# python3
class SlashDict:
def __init__(self, data):
print(type(self))
self.data = data
self.cache_ok = False
self.cache = []
def get(self, key):
terms = key.split('/')
temp = self.data
for i in range(len(terms)):
temp = temp[terms[i]]
return temp
def pop(self, key):
terms = key.split('/')
temp = self.data
for i in range(len(terms) - 1):
temp = temp[terms[i]]
ret = temp[terms[-1]]
del temp[terms[-1]]
self.cache_ok = False
return ret
def __str__(self):
return str(self.data)
def __getitem__(self, key):
terms = key.split('/')
temp = self.data
for i in range(len(terms)):
temp = temp[terms[i]]
return temp
def __setitem__(self, key, value):
terms = key.split('/')
temp = self.data
for i in range(len(terms)-1):
if terms[i] not in temp or not isinstance(temp[terms[i]],dict):
temp[terms[i]] ={}
temp = temp[terms[i]]
temp[terms[-1]] = value
self.cache_ok = False
def deep_keys(self):
if self.cache_ok:
pass
else:
self.cache = []
def digui(d,s):
for key in d:
if isinstance(d[key],dict):
digui(d[key],s+'/'+key)
else:
final = s + '/' + key
final = final.lstrip('/')
self.cache.append(final)
digui(self.data,'')
self.cache_ok = True
return self.cache
if __name__ == '__main__':
d = SlashDict({'a': {'b': {'c': {'x': 1, 'y': 2}}, 'd': 3}, 'e': {'f': 4}})
d2 = SlashDict({'t'})
print(d.data)
print(d['a/b/c'])
print(d['a/d'])
print(d.pop('a/b/c/y'))
d['e/f/g'] = 5
print(d)
print(d.deep_keys())
```
之前有个笔试里写过,看流畅的python里说直接继承内置dict有坑(dict可能不会使用用户定义的方法),可以用组合或者继承collections.UserDict
Let's go pythonic!
为了避免论坛里看起来臃肿,发帖时把注释都去了
带注释的版本见上传文件 或者 参见 https://github.com/Maxlinn/self-contained-progs/blob/main/pathdict.py
```python
from collections import UserDict
class PathDict(UserDict):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def __getitem__(self, item: str):
it = self.data
segments = item.split('/')
for seg in segments:
if not isinstance(it, dict):
raise KeyError(f"stem '{seg}' of '{item}' already has a non-mapping object.")
if seg not in it.keys():
raise KeyError(f"stem '{seg}' of '{item}' does not exist.")
it = it[seg]
return it
def __setitem__(self, key: str, value):
it = self.data
segments = key.split('/')
for i, seg in enumerate(segments):
if i < (len(segments) - 1):
if not isinstance(it, dict):
raise KeyError(f"stem '{seg}' of '{key}' already has a non-mapping object.")
if seg not in it.keys():
it[seg] = {}
it = it[seg]
else:
it[seg] = value
if __name__ == '__main__':
# test case of https://bbs.byr.cn/#!article/Python/26174
d = PathDict({'a': {'b': 1, 'c': 2}})
print(d)
print(d['a/b'])
d['e/f/g'] = 2
print(d)
```
【 在 Xudongyu 的大作中提到: 】
: 一道面试题,大致意思是实现一个dict,可能存在字典嵌套,用‘/’表示层级,其余和传统dict一致。例:
: dict_1{‘a’:{‘b’:1, ‘c’:2}}
: Input : dict_1[‘a/b’]
: ...................
【 在 p146818 的大作中提到: 】
: ax量化的题目?
是的,我那会写着隐约记得哪里说过__getitem__不能随便重写,然后就想了2小时
我以为可以直接用hashmap实现[ema1]
【 在 nemosc 的大作中提到: 】
: [md]
: ```
: # python3
: ............