按其祖先分组项目

huangapple go评论59阅读模式
英文:

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']] using str.split().
  • Write a function make_groups that groups by first element.
  • Write a recursive function make_tree that applies make_groups once, then applies make_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,

  1. we can Sort our list based on the elements structure
  2. Reformat the list elements by finding the "Head" element and create a tail structure.
  3. Finally we append them to our dictionary

Here is my main code

l=[&#39;1&#39;, &#39;1.1&#39;, &#39;1.1.1&#39;, &#39;1.1.2&#39;, &#39;1.1.3&#39;,&#39;1.1.2.1&#39;,&#39;2&#39;, &#39;2.1&#39;, &#39;2.2&#39;, &#39;3&#39;]
t=l.copy()
from functions import maxd,d,head,apnd,disp
for j in range(0,len(t)):
i=0
while i&lt;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(&#39;.&#39;))
else:
x=list(x.keys())[0]
return d(x)
def comp(a,b):
A=a.split(&#39;.&#39;)
B=b.split(&#39;.&#39;)
n=min(len(A),len(B))
for i in range(0,n):
if int(A[i])&gt;int(B[i]):
return True
elif int(A[i])&lt;int(B[i]):
return False
else:
if len(A)&gt;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&lt;(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)&gt;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(&#39;^&#39;+t[i],x):
return i
else:
if re.search(&#39;^&#39;+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])

huangapple
  • 本文由 发表于 2023年2月18日 22:18:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/75493945.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定