英文:
How to convert a list of lists into a multi-level nested dictionary?
问题
I want to convert a list of lists to multi-level nested dictionaries like so:
x = [[1, 2, 3, 4],
[1, 2, 4, 5],
[5, 6, 7, 8]]
print(f(x))
## {
## 1: {2: {3: 4,
## 4: 5}
## },
## 5: {6: {7: 8}}
## }
The list inside can be arbitrary long. Any ideas would be very helpful. For any set of nested keys, there is only one unique value possible. Thank you. So, the list mentioned below does not occur:
x = [[1,2,3,4],
[1,2,3,5]]
I tried the function below but it throws an AttributeError: 'int' object has no attribute 'keys'.
Also, it updates incorrectly as mentioned below, so not very helpful.
def listoflists_dict(listformat):
a = dict()
cur = a
for inner_list in listformat:
for i, ele in enumerate(inner_list):
print(a)
if (ele not in cur.keys()) and (i < len(inner_list) - 1):
cur[ele] = dict()
cur = cur[ele]
elif (ele not in cur.keys()) and (i == len(inner_list) - 1):
cur[ele] = inner_list[-1]
else:
cur = cur[ele]
return a
listformat = [[1, 2, 3, 4],
[1, 2, 4, 5],
[5, 6, 7, 8]]
listoflists_dict(listformat)
## {}
## {1: {}}
## {1: {2: {}}}
## {1: {2: {3: {}}}
## {1: {2: {3: {4: 4}}}
## {1: {2: {3: {4: 4, 1: {}}}}
## {1: {2: {3: {4: 4, 1: {2: {}}}}}
## {1: {2: {3: {4: 4, 1: {2: {4: {}}}}}}
## {1: {2: {3: {4: 4, 1: {2: {4: {5: 5}}}}}}
## {1: {2: {3: {4: 4, 1: {2: {4: {5: 5}}}}}}
英文:
I want to convert a list of lists to multi-level nested dictionaries like so:
x = [[1, 2, 3, 4],
[1, 2, 4, 5],
[5, 6, 7, 8]]
print(f(x))
## {
## 1: {2: {3: 4,
## 4: 5}
## },
## 5: {6: {7: 8}}
## }
The list inside can be arbitrary long. Any ideas would be very helpful. For any set of nested keys, there is only one unique value possible. Thank you. So, the list mentioned below does not occur:
x = [[1,2,3,4],
[1,2,3,5]]
I tried the function below but it throws an AttributeError: 'int' object has no attribute 'keys'.
Also, it updates incorrectly as mentioned below, so not very helpful.
def listoflists_dict(listformat):
a = dict()
cur = a
for inner_list in listformat:
for i, ele in enumerate(inner_list):
print(a)
if (ele not in cur.keys()) and (i < len(inner_list) - 1):
cur[ele] = dict()
cur = cur[ele]
elif (ele not in cur.keys()) and (i == len(inner_list) - 1):
cur[ele] = inner_list[-1]
else:
cur = cur[ele]
return a
listformat = [[1, 2, 3, 4],
[1, 2, 4, 5],
[5, 6, 7, 8]]
listoflists_dict(listformat)
## {}
## {1: {}}
## {1: {2: {}}}
## {1: {2: {3: {}}}}
## {1: {2: {3: {4: 4}}}}
## {1: {2: {3: {4: 4, 1: {}}}}}
## {1: {2: {3: {4: 4, 1: {2: {}}}}}}
## {1: {2: {3: {4: 4, 1: {2: {4: {}}}}}}}
## {1: {2: {3: {4: 4, 1: {2: {4: {5: 5}}}}}}}
## {1: {2: {3: {4: 4, 1: {2: {4: {5: 5}}}}}}}
答案1
得分: 0
以下是翻译好的内容:
好主意,存在两个主要问题:
- 你没有为每个
ele
重置cur
。将cur = a
的位置下移一行将解决这个问题。 - 需要特殊处理的元素是
len(inner_list) - 2
,而不是len(inner_list) - 1
。你不应该处理len(inner_list) - 1
,所以使用break
会很有用。
有了这些修改,你的代码如下所示:
def listoflists_dict(listformat):
a = dict()
for inner_list in listformat:
cur = a
for i, ele in enumerate(inner_list):
if (ele not in cur.keys()) and (i < len(inner_list) - 2):
cur[ele] = dict()
cur = cur[ele]
elif (ele not in cur.keys()) and (i == len(inner_list) - 2):
cur[ele] = inner_list[-1]
break
else:
cur = cur[ele]
return a
现在,以下是一些非必要的注释:
ele not in cur.keys()
会顺序测试cur
中的每个键,因为cur.keys()
是一个生成器;ele not in cur
将直接测试字典中是否存在键,因此更可取。- 同样,
{}
作为文字比必须调用函数的dict()
更快。 - 比起不得不检查它们,更容易将最后两个元素分离出来。
有了这些,这是一个更快和更简洁的版本:
def listoflists_dict(listformat):
a = {}
for *path, key, val in listformat:
cur = a
for ele in path:
if ele not in cur:
cur[ele] = {}
cur = cur[ele]
cur[key] = val
return a
英文:
Good idea, with two major problems:
- You don't reset
cur
for eachele
. Movingcur = a
one line down will fix this problem. - The element that needs special handling is
len(inner_list) - 2
, notlen(inner_list) - 1
. You must not processlen(inner_list) - 1
, so abreak
is useful.
With this, your code becomes:
def listoflists_dict(listformat):
a = dict()
for inner_list in listformat:
cur = a
for i, ele in enumerate(inner_list):
if (ele not in cur.keys()) and (i < len(inner_list) - 2):
cur[ele] = dict()
cur = cur[ele]
elif (ele not in cur.keys()) and (i == len(inner_list) - 2):
cur[ele] = inner_list[-1]
break
else:
cur = cur[ele]
return a
Now, several non-essential comments:
ele not in cur.keys()
will sequentially test each key incur
, sincecur.keys()
is a generator;ele not in cur
will directly test if a key is present in a dict, and should therefore be preferred- Similarly,
{}
, as a literal is faster thandict()
, which must invoke a function - It is easier to tear off the last two elements, rather than having to check for them
With that, here is a faster and sleeker version:
def listoflists_dict(listformat):
a = {}
for *path, key, val in listformat:
cur = a
for ele in path:
if ele not in cur:
cur[ele] = {}
cur = cur[ele]
cur[key] = val
return a
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论