我确实有一个列表,如下所示 -
keyList1 = ["Person", "Male", "Boy", "Student", "id_123", "Name"]
value1 = "Roger"
如何生成可以检索的动态字典 -
mydict["Person"]["Male"]["Boy"]["Student"]["id_123"]["Name"] = value
列表可以是任何内容;可变长度或由“N”个未知的元素组成......
现在我有另一个列表,因此我的字典应该相应更新
keyList2 = ["Person", "Male", "Boy", "Student", "id_123", "Age"]
value2 = 25
即。如果密钥“人”,“男”,“男孩”,“学生”,“id_123”已经存在,则应附加新的密钥“年龄”......
答案 0 :(得分:8)
我只是在学习python,所以我的代码可能不是非常pythonic,但这里是我的代码
d = {}
keyList1 = ["Person", "Male", "Boy", "Student", "id_123", "Name"]
keyList2 = ["Person", "Male", "Boy", "Student", "id_123", "Age"]
value1 = "Roger"
value2 = 3
def insert(cur, list, value):
if len(list) == 1:
cur[list[0]] = value
return
if not cur.has_key(list[0]):
cur[list[0]] = {}
insert(cur[list[0]], list[1:], value)
insert(d, keyList1, value1)
insert(d, keyList2, value2)
{'Person': {'Male': {'Boy': {'Student': {'id_123': {'Age': 3, 'Name': 'Roger'}}}}}}
答案 1 :(得分:4)
您可以通过嵌套defaultdict
s来执行此操作:
from collections import defaultdict
def recursive_defaultdict():
return defaultdict(recursive_defaultdict)
def setpath(d, p, k):
if len(p) == 1:
d[p[0]] = k
else:
setpath(d[p[0]], p[1:], k)
mydict = recursive_defaultdict()
setpath(mydict, ["Person", "Male", "Boy", "Student", "id_123", "Name"], 'Roger')
print mydict["Person"]["Male"]["Boy"]["Student"]["id_123"]["Name"]
# prints 'Roger'
这具有能够写
的好处mydict['a']['b'] = 4
无需使用setpath
帮助程序。
你可以在没有递归defaultdict
的情况下做到这一点:
def setpath(d, p, k):
if len(p) == 1:
d[p[0]] = k
else:
setpath(d.setdefault(p[0], {}), p[1:], k)
答案 2 :(得分:3)
也许你可以继承dict:
class ChainDict(dict):
def set_key_chain(self, keyList, value):
t = self
for k in keyList[:-1]:
t = t.setdefault(k, {})
t.setdefault(keyList[-1], value)
c = ChainDict()
c.set_key_chain(['Person', 'Male', 'Boy', 'Student', 'id_123', 'Name'], 'Roger')
print c
>>{'Person': {'Male': {'Boy': {'Student': {'id_123': {'Name': 'Roger'}}}}}}
c.set_key_chain(['Person', 'Male', 'Boy', 'Student', 'id_123', 'Age'], 25)
print c
>>{'Person': {'Male': {'Boy': {'Student': {'id_123': {'Age': 25,
'Name': 'Roger'}}}}}}
答案 3 :(得分:1)
创建自己的派生自dict的类,其中 init 方法将列表和单个值作为输入并迭代列表设置键值,定义一个列表的更新方法和一个新值,对于每个尚未成为键的项目,将其设置为新值,(假设这是您所需要的)。
忘记
的想法mydict [“Person”] [“男性”] [“男孩”] [“学生”] [“id_123”] [“姓名”] = value1`
因为它与子指数混淆。
答案 4 :(得分:0)
我正在尝试处理类似的事情,所以我可以提出一些指导方针,但我再次在Python中很天真,所以这只是一个指导原则......
你有一个按键列表 ,所以你绝对可以从为每个值迭代循环开始,然后分配值
像
for i in keylist:
if type(keylist[i]) == dict:
do something
else:
keylist[i] = {}
在做某事时,你需要增加i并将索引更改为[i] [i + 1]然后按照相同的直到i + n = len(密钥列表)
答案 5 :(得分:0)
使用tuple(keyList1)
作为密钥。 (元组是不可变的,因此可以是字典键)。
使用嵌套式dict方法会让您感到头疼。 (用于枚举的嵌套循环,层次结构需要更改时的遗留数据等)。
再想一想,也许你应该定义一个人类
class Person(object):
gender = "Male"
group = "Student"
id = 123
Name = "John Doe"
然后使用所有人的列表并过滤例如。
male_students = [s for s in ALL_PERSONS where s.gender=="Male" and s.group="Student"]
...对于< = 10000名学生,你应该表现得很好。
答案 6 :(得分:-2)
>>> mydict = {}
>>> keyList1 = ["Person", "Male", "Boy", "Student", "id_123", "Name"]
>>> value1 = "Roger"
>>> reduce(lambda x, y: x.setdefault(y, {}), keyList1, mydict)
{}
>>> mydict["Person"]["Male"]["Boy"]["Student"]["id_123"]["Name"] = value1
您也可以像这样一步完成
>>> keyList2 = ["Person", "Male", "Boy", "Student", "id_123", "Age"]
>>> value2 = 25
>>> reduce(lambda x,y: x.setdefault(y,{}), keyList2[:-1], mydict).update({keyList2[-1]: value2})