【问题标题】:Determine number of leaf nodes in tree vs. non-leaf nodes确定树中叶节点与非叶节点的数量
【发布时间】:2020-06-10 14:03:19
【问题描述】:

我有一本包含子词典的词典。它是一个具有节点、一些叶节点和一些非叶节点的决策树。给定字典,我如何计算其中的每一个?

例如:

{'Outlook': {'Overcast': 'Yes', 'Rain': {'Wind': {'Strong': 'No', 'Weak': 'Yes'}}, 'Sunny': {'Humidity': {'High': 'No', 'Normal': 'Yes'}}}}

这会生成如下所示的树:

其中有三个非叶子节点和五个叶子节点。我对如何做到这一点有一个大致的了解:

def count(d):
  a, b = 0, 0 # non-leaf nodes and leaf nodes
  for key, value in d.items():
    if isinstance(value, dict):
      a += 1
      # some recursive call on value
    else:
      b+= 1
  return a, b

但我不确定如何组织递归调用。有内置方法吗?

【问题讨论】:

  • 不确定我是否理解错了,但dicts应该返回(x := count(value))[0] +1, x[1],而非dicts返回a, b+1吗?
  • 只是为了澄清:您希望在递归期间如何处理 a、b?您想要每个级别的 a、b,还是只想要整个递归的总 a、b?
  • 需要注意的是root dict的key是分支,root dict的value是新节点。休息很简单,我在下面给出了正确的输出 3、5 的代码。

标签: python dictionary tree decision-tree


【解决方案1】:

这就是你要找的东西:

def get_count(d, c = {0:0, 1:0}):
    c[0]+=1    #count non-leaf nodes
    nodes = d.keys()
    for node in nodes:
      subnodes = d[node].values()
      for subnode in subnodes:
          if isinstance(subnode, dict)           
              get_count(subnode,c)
          else:
              c[1]+=1  #count leaf nodes

    return c




d = {'Outlook': {'Overcast': 'Yes', 'Rain': {'Wind': {'Strong': 'No', 'Weak': 'Yes'}}, 'Sunny': {'Humidity': {'High': 'No', 'Normal': 'Yes'}}}}

print(get_count(d))

输出:3,5

3 : 非叶节点个数

5:没有。叶节点数

【讨论】:

  • 我明白你的意思。统计当前节点的子节点和值,然后递归到每个子节点。
  • 没错。这里棘手的部分是在字典中表示为根中的键的分支。我们不需要计算这些分支。休息很简单。如果对您有帮助,请不要忘记标记为已回答。
  • 像 d["Outlook"].keys() 会给你 Outlook 节点的分支,而 d[branch].values() 会从那个分支给你更多的节点
【解决方案2】:

你可以做的很简单

def count(d):
  a, b = 0, 0 # subdicts and not-subdicts
  for key, value in d.items():
    if isinstance(value, dict):
      a += 1
      suba, subb = count(value)
      a += suba
      b += subb
    else:
      b += 1
  return a, b

但是,您的示例有五个“非字典”和五个“字典”。

【讨论】:

    【解决方案3】:

    一种可能性是创建一个存储计数的运行字典:

    def get_count(d, c):
      for a, b in d.items():
        c[isinstance(b, dict)] += 1
        if isinstance(b, dict):
           get_count(b, c)
    
    
    d = {'Outlook': {'Overcast': 'Yes', 'Rain': {'Wind': {'Strong': 'No', 'Weak': 'Yes'}}, 'Sunny': {'Humidity': {'High': 'No', 'Normal': 'Yes'}}}}
    c = {0:0, 1:0}
    get_count(d, c)
    print(c)
    

    输出:

    {0: 5, 1: 5}
    #0: elements, #1: sub-dictionaries 
    

    【讨论】:

    • 你的解决方案不正确,因为他专门询问了叶子节点和非叶子节点的数量。输出应该是 3,5。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-19
    • 1970-01-01
    相关资源
    最近更新 更多