英文:
Group items by their ancestors
问题
假设我们有一个数组:
l = ["1", "1.1", "1.1.1", "2", "3"]
构建这样的字典结构的高效方法是什么:
d = {"1": [{"1.1": [{"1.1.1": []}]}], "2": [], "3": []}
英文:
Assume we have an array:
l = ["1", "1.1", "1.1.1", "2", "3"]
What is the efficent way to build such dict structure:
d = {"1": [{"1.1": [{"1.1.1": []}]}], "2": [], "3": []}
答案1
得分: 1
我建议分三个步骤来完成。
- 使用
str.split()
将l
转换为[['1'], ['1', '1'], ['1', '1', '1'], ['2'], ['3']]
。 - 编写一个名为
make_groups
的函数,根据第一个元素进行分组。 - 编写一个递归函数
make_tree
,首先应用make_groups
一次,然后对每个组递归应用make_tree
。
如果这是为了学习目的,我鼓励您尝试按照上述三点操作,不要查看下面的代码。
l0 = ["1", "1.1", "1.1.1", "2", "3"]
l = 展开收缩 # [['1'], ['1', '1'], ['1', '1', '1'], ['2'], ['3']]
def make_groups(l, depth=0):
d = {}
for x in l:
if len(x) > depth:
d.setdefault('.'.join(x[:depth+1]), []).append(x)
return d
def make_tree(l, depth=0):
d = make_groups(l, depth)
for k, v in d.items():
d[k] = make_tree(v, depth+1)
return d
以上是翻译好的代码部分。
英文:
I suggest doing it in three steps.
- Transform
l
into[['1'], ['1', '1'], ['1', '1', '1'], ['2'], ['3']]
usingstr.split()
. - Write a function
make_groups
that groups by first element. - Write a recursive function
make_tree
that appliesmake_groups
once, then appliesmake_tree
recursively to each group.
If this is for learning purposes, I encourage you to try following the three points above, without looking at the code below.
l0 = ["1", "1.1", "1.1.1", "2", "3"]
l = 展开收缩 # [['1'], ['1', '1'], ['1', '1', '1'], ['2'], ['3']]
def make_groups(l, depth=0):
d = {}
for x in l:
if len(x) > depth:
d.setdefault('.'.join(x[:depth+1]), []).append(x)
return d
# print(make_groups(l))
# {'1': [['1'], ['1', '1'], ['1', '1', '1']], '2': [['2']], '3': [['3']]}
def make_tree(l, depth=0):
d = make_groups(l, depth)
for k, v in d.items():
d[k] = make_tree(v, depth+1)
return d
# print(make_tree(l))
# {'1': {'1.1': {'1.1.1': {}}}, '2': {}, '3': {}}
答案2
得分: 0
这实际上相当简单。请注意,它需要格式良好的列表,也就是说,你不能从1跳到1.1.1,例如。
首先,为每个值构建一个以该值为键,空列表为值的字典。然后遍历每个键,如果它包含一个“.”,那么前面的“.”左边的键就是父键,将这个字典附加到父键的列表中。
最后,移除所有包含“.”的键。
d = {e:[] for e in l}
for k, v in d.items():
if "." in k:
p = k[:k.rindex(".")]
d.append({k:v})
d = {k: v for k, v in d.items() if "." not in k}
print(d)
{'1': [{'1.1': [{'1.1.1': []}]}], '2': [], '3': []}
注意:代码部分不翻译,仅提供翻译后的注释。
英文:
This is actually pretty simple. Note it requires well formed list that is you can't jump to 1.1.1 from 1 for example.
First build a dictionary for each value as key and empty list as value. And then go through each key and if it has a "." then go to the key which is to left of the "." and append this dictionary to the list for that parent key.
And finally remove all the keys which have a "."
d = {e:[] for e in l}
for k, v in d.items():
if "." in k:
p = k[:k.rindex(".")]
d.append({k:v})
d = {k: v for k, v in d.items() if "." not in k}
print(d)
{'1': [{'1.1': [{'1.1.1': []}]}], '2': [], '3': []}
答案3
得分: 0
以下是您的代码的中文翻译:
对于一个更基本/基础的方法,不使用递归,可以执行以下步骤:
1. 根据元素结构对列表进行排序。
2. 通过查找“Head”元素并创建一个尾部结构,重新格式化列表元素。
3. 最后,将它们附加到我们的字典中。
以下是我的主要代码:
```python
l = ['1', '1.1', '1.1.1', '1.1.2', '1.1.3', '1.1.2.1', '2', '2.1', '2.2', '3']
t = l.copy()
from functions import maxd, d, head, apnd, disp
for j in range(0, len(t)):
i = 0
while i < len(t):
if d(t[i]) == maxd(t):
h = head(t, t[i])
if type(t[i]) == str:
t[i] = {t[i]: []}
apnd(t, h, i)
i = i + 1
print(t)
disp(t)
以下是函数定义部分的翻译:
def d(x):
if type(x) == str:
return len(x.split('.'))
else:
x = list(x.keys())[0]
return d(x)
def comp(a, b):
A = a.split('.')
B = b.split('.')
n = min(len(A), len(B)
for i in range(0, n):
if int(A[i]) > int(B[i]):
return True
elif int(A[i]) < int(B[i]):
return False
else:
if len(A) > len(B):
return True
else:
return False
def swap(l, a, b):
temp = l[a]
l[a] = l[b]
l[b] = temp
def sort(l):
for j in range(0, len(l) - 1):
for i in range(0, len(l) - 1):
if comp(l[i], l[i+1]) == True:
swap(l, i, i+1)
return l
def lstfmt(l):
i = 0
while i < (len(l) - 1):
if d(l[i]) == d(l[i+1]):
k = i + 1
while(d(l[i]) == d(l[k])):
k = k + 1
l[i] = l[i:k]
del l[i+1:k]
i = i + 1
return l
def maxd(l):
maxd = 0
for i in l:
if d(i) > maxd:
maxd = d(i)
return maxd
import re
def head(t, x):
if type(x) == str:
for i in range(0, len(t)):
if x != t[i]:
if d(x) == d(t[i]) + 1:
if type(t[i]) == str:
if re.search('^' + t[i], x):
return i
else:
if re.search('^' + list(t[i].keys())[0], x):
return i
else:
try:
return t.index(x)
except ValueError:
return -1
else:
x = list(x.keys())[0]
return head(t, x)
def apnd(t, a, b):
if a != -1:
if a != b:
if type(t[a]) == str:
t[a] = {t[a]: [t[b]]}
else:
t[a][list(t[a].keys())[0]].append(t[b])
del t[b]
if a == -1:
if type(t[b]) == str:
t[b] = {t[b]: []}
def disp(l):
for i in l:
for j in i:
print(j)
print(i[j])
希望这能帮助您理解代码的功能。
英文:
For a more basic/fundamental approach without any recursion,
- we can Sort our list based on the elements structure
- Reformat the list elements by finding the "Head" element and create a tail structure.
- Finally we append them to our dictionary
Here is my main code
l=['1', '1.1', '1.1.1', '1.1.2', '1.1.3','1.1.2.1','2', '2.1', '2.2', '3']
t=l.copy()
from functions import maxd,d,head,apnd,disp
for j in range(0,len(t)):
i=0
while i<len(t):
#if j==4 and i==0:print(t)
if d(t[i])==maxd(t):
h=head(t,t[i])
if type(t[i])==str:t[i]={t[i]:[]}
apnd(t,h,i)
i=i+1
print(t)
disp(t)
and here is the functions definition
def d(x):
if type(x)==str:return len(x.split('.'))
else:
x=list(x.keys())[0]
return d(x)
def comp(a,b):
A=a.split('.')
B=b.split('.')
n=min(len(A),len(B))
for i in range(0,n):
if int(A[i])>int(B[i]):
return True
elif int(A[i])<int(B[i]):
return False
else:
if len(A)>len(B):
return True
else:
return False
def swap(l,a,b):
temp=l[a]
l[a]=l[b]
l[b]=temp
def sort(l):
for j in range(0,len(l)-1):
for i in range(0,len(l)-1):
if comp(l[i],l[i+1])==True:
swap(l,i,i+1)
return l
def lstfmt(l):
i=0
while i<(len(l)-1):
if d(l[i])==d(l[i+1]):
k=i+1
while(d(l[i])==d(l[k])):
k=k+1
l[i]=l[i:k]
del l[i+1:k]
i=i+1
return l
def maxd(l):
maxd=0
for i in l:
if d(i)>maxd:
maxd=d(i)
return maxd
import re
def head(t,x):
if type(x)==str:
for i in range(0,len(t)):
if x!=t[i]:
if d(x)==d(t[i])+1:
if type(t[i])==str:
if re.search('^'+t[i],x):
return i
else:
if re.search('^'+list(t[i].keys())[0],x):
return i
else:
try:return t.index(x)
except ValueError:return -1
else:
x=list(x.keys())[0]
return head(t,x)
def apnd(t,a,b):
if a!=-1:
if a!=b:
if type(t[a])==str:
t[a]={t[a]:[t[b]]}
else:
t[a][list(t[a].keys())[0]].append(t[b])
del t[b]
if a==-1:
if type(t[b])==str:t[b]={t[b]:[]}
def disp(l):
for i in l:
for j in i:
print(j)
print(i[j])
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论