如何在里面有列表的情况下扩展 python 字典
how to extend a python dictionary while there are list inside
我试过像 mongodb 那样从字典中获取数据。
虽然有这样的文档
{'a': 'b', 'c': ['d', {'e': ['i', {'j': 'h'}]}]}
我想从搜索字符串中获取值 'h',例如 'c.e.j',因为 mongodb 可以
> db.cc.findOne({'c.e.j':'h'})
{
"_id" : ObjectId("551e5047342b12656b4edecc"),
"a" : "b",
"c" : [
"d",
{
"e" : [
"i",
{
"j" : "h"
}
]
}
]
}
所以我第一个想到的是我需要为里面的每个列表扩展字典,我已经编码了 4 个小时,我觉得这对我来说很难。
我的代码的最终版本如下所示:
import types
def extdic(cc):
lst = []
for key in cc:
value = cc[key]
if type(value) == types.DictType:
for _ in extdic(value):
cc[key] = _
lst.append(eval(repr(cc)))
return lst
if type(value) == types.ListType:
#print cc
for _ in value:
cc[key] = _
lst.append(eval(repr(cc)))
#print lst
return lst
else:
return [cc]
def mkdic(cc):
lst = []
if type(cc) == types.ListType:
lst = cc
else:
lst = [cc]
reslst = []
while True:
for _ in lst:
#print _
ext = extdic(_)
#print ext
reslst = reslst + ext
if len(reslst) == len(lst):
break
else:
lst = reslst
reslst = []
return lst
if __name__ == '__main__':
cc = [
{'a': 'b', 'c': ['d', {'e': ['i', 'j']}]},
{'f':['g','h']}
]
cd = {'a': 'b', 'c': {'e': ['i', 'j']}}
ce = {'a': {'b': {'c':{'d':{'e':['f','g']}}}}}
for _ in mkdic(cc):
print _
遗憾的是我还是得不到我想要的
我只得到 'ce' 词典,就像
MBA:code cc$ python todic3.py
{'a': {'b': {'c': {'d': {'e': 'f'}}}}}
{'a': {'b': {'c': {'d': {'e': 'g'}}}}}
MBA:code cc$
其他字典结构仍然不是我想要的..
MBA:code cc$ python todic3.py
{'a': 'b', 'c': ['d', {'e': ['i', {'j': 'h'}]}]}
{'f': 'g'}
{'f': 'h'}
MBA:code cc$
我想使用像
这样的工具
MBA:code cc$ echo "{'a': 'b', 'c': ['d', {'e': ['i', {'j': 'h'}]}]}" | python todic3.py c.e.j
c.e.j: h
MBA:code cc$
请帮忙..
非常感谢
这应该是return指定的值。 'yield from' 语句要求您使用 Python 3。
很遗憾,我无法在 ATM 上进行测试。
编辑:我刚才测试了它,结果发现那里有一些重大错误。我修复了它们,它现在可以正常工作了。
def iter_flattened(data):
'''returns a generator that allows iteration over key,value pairs, even if the dictionaries are nested in lists'''
if isinstance(data, dict):
yield from data.items()
elif isinstance(data, list):
for item in data:
yield from iter_flattened(item)
def _find(data, keys):
'''This function searches the given (sub-)tree for the given keys'''
if len(keys) == 0:
return data
for key, value in iter_flattened(data):
if key == keys[0]:
result = _find(value, keys[1:])
else:
result = _find(value, keys)
if result is not None:
return result
return None
def find(data, path):
'''Interface function, that accepts the keys as a string seperated with dots.'''
keys = path.split('.')
return _find(data, keys)
这样使用:
data = {'a': 'b', 'c': ['d', {'e': ['i', {'j': 'h'}]}]}
value = find(data, 'c.e.j')
print(value) # --> h
我试过像 mongodb 那样从字典中获取数据。
虽然有这样的文档
{'a': 'b', 'c': ['d', {'e': ['i', {'j': 'h'}]}]}
我想从搜索字符串中获取值 'h',例如 'c.e.j',因为 mongodb 可以
> db.cc.findOne({'c.e.j':'h'})
{
"_id" : ObjectId("551e5047342b12656b4edecc"),
"a" : "b",
"c" : [
"d",
{
"e" : [
"i",
{
"j" : "h"
}
]
}
]
}
所以我第一个想到的是我需要为里面的每个列表扩展字典,我已经编码了 4 个小时,我觉得这对我来说很难。
我的代码的最终版本如下所示:
import types
def extdic(cc):
lst = []
for key in cc:
value = cc[key]
if type(value) == types.DictType:
for _ in extdic(value):
cc[key] = _
lst.append(eval(repr(cc)))
return lst
if type(value) == types.ListType:
#print cc
for _ in value:
cc[key] = _
lst.append(eval(repr(cc)))
#print lst
return lst
else:
return [cc]
def mkdic(cc):
lst = []
if type(cc) == types.ListType:
lst = cc
else:
lst = [cc]
reslst = []
while True:
for _ in lst:
#print _
ext = extdic(_)
#print ext
reslst = reslst + ext
if len(reslst) == len(lst):
break
else:
lst = reslst
reslst = []
return lst
if __name__ == '__main__':
cc = [
{'a': 'b', 'c': ['d', {'e': ['i', 'j']}]},
{'f':['g','h']}
]
cd = {'a': 'b', 'c': {'e': ['i', 'j']}}
ce = {'a': {'b': {'c':{'d':{'e':['f','g']}}}}}
for _ in mkdic(cc):
print _
遗憾的是我还是得不到我想要的
我只得到 'ce' 词典,就像
MBA:code cc$ python todic3.py
{'a': {'b': {'c': {'d': {'e': 'f'}}}}}
{'a': {'b': {'c': {'d': {'e': 'g'}}}}}
MBA:code cc$
其他字典结构仍然不是我想要的..
MBA:code cc$ python todic3.py
{'a': 'b', 'c': ['d', {'e': ['i', {'j': 'h'}]}]}
{'f': 'g'}
{'f': 'h'}
MBA:code cc$
我想使用像
这样的工具MBA:code cc$ echo "{'a': 'b', 'c': ['d', {'e': ['i', {'j': 'h'}]}]}" | python todic3.py c.e.j
c.e.j: h
MBA:code cc$
请帮忙..
非常感谢
这应该是return指定的值。 'yield from' 语句要求您使用 Python 3。
很遗憾,我无法在 ATM 上进行测试。
编辑:我刚才测试了它,结果发现那里有一些重大错误。我修复了它们,它现在可以正常工作了。
def iter_flattened(data):
'''returns a generator that allows iteration over key,value pairs, even if the dictionaries are nested in lists'''
if isinstance(data, dict):
yield from data.items()
elif isinstance(data, list):
for item in data:
yield from iter_flattened(item)
def _find(data, keys):
'''This function searches the given (sub-)tree for the given keys'''
if len(keys) == 0:
return data
for key, value in iter_flattened(data):
if key == keys[0]:
result = _find(value, keys[1:])
else:
result = _find(value, keys)
if result is not None:
return result
return None
def find(data, path):
'''Interface function, that accepts the keys as a string seperated with dots.'''
keys = path.split('.')
return _find(data, keys)
这样使用:
data = {'a': 'b', 'c': ['d', {'e': ['i', {'j': 'h'}]}]}
value = find(data, 'c.e.j')
print(value) # --> h