如何从提供的数据递归地创建字典结构?

2024-05-16 06:49:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我有下面提到的元组列表,元组中的第一个元素是键,我想根据它生成特定格式的字典。你知道吗

# list variable
x = [  
(('Fresh Vegetables', 'Hamel', '2006', "Jimmy's Ebony Sweet Peas"), 209034.60000000001), 

(('Fresh Vegetables', 'Hamel', '2006', "Sue's Ebony Asparagus"), 217158.67000000001), 

(('Fresh Vegetables', 'Mentor', '2007', "Jimmy's Ebony Sweet Peas"), 225630.60000000001), 

(('Fresh Vegetables', 'Mentor', '2007',"Sue's Ebony Asparagus"), 233201.47), 

(('Fresh Vegetables', 'Hamel', '2006', "Bubba's Ebony Corn on the Cob"), 317588.95000000001), 

(('Fresh Vegetables','Mentor', '2007', "Bubba's Ebony Corn on the Cob"), 343151.59000000003), 

(('Fresh Vegetables', 'Sioux Center', '2007', "John's Ebony Squash"), 401308.01 000000001)
]

我想要下面给出的词典结构。其中“total”键是该字典中每个字典元素的总和。你知道吗

finalX = {
   'Fresh Vegetables':{

       'Hamel':{

           '2006':{

                 "Jimmy's Ebony Sweet Peas":209034.60000000001,
                 "Sue's Ebony Asparagus":217158.67000000001,
                 "Bubba's Ebony Corn on the Cob":317588.95000000001,
                 "total": 743782.22
            }
           "total":743782.22
       },   

       'Mentor':{

           '2007':{

               "Jimmy's Ebony Sweet Peas":225630.60000000001,
               "Sue's Ebony Asparagus":233201.47,
               "Bubba's Ebony Corn on the Cob":343151.59000000003,
               "total": 801983.66
           }
           "total":801983.66
       },

       'Sioux Center':{

           '2007':{

               "John's Ebony Squash":401308.01000000001
               "total":401308.01
           }
           "total":401308.01
       }
       "total":1947073.89
   }
}

我知道没有递归是不可能的,但我被困在那里。如何实施?我试过一些事,但做不到。你知道吗


Tags: theontotaljimmysweetmentorfreshsue
3条回答

迭代方法:首先将其设置为dict,然后添加小计:

import pprint

x = [
(('Fresh Vegetables', 'Hamel', '2006', "Jimmy's Ebony Sweet Peas"), 209034.60000000001),    
(('Fresh Vegetables', 'Hamel', '2006', "Sue's Ebony Asparagus"), 217158.67000000001),    
(('Fresh Vegetables', 'Mentor', '2007', "Jimmy's Ebony Sweet Peas"), 225630.60000000001),     
(('Fresh Vegetables', 'Mentor', '2007',"Sue's Ebony Asparagus"), 233201.47),    
(('Fresh Vegetables', 'Hamel', '2006', "Bubba's Ebony Corn on the Cob"), 317588.95000000001),     
(('Fresh Vegetables','Mentor', '2007', "Bubba's Ebony Corn on the Cob"), 343151.59000000003),     
(('Fresh Vegetables', 'Sioux Center', '2007', "John's Ebony Squash"), 401308.01000000001)]

创建字典:

XX = {}
for n in x:
  what = n[0][0]
  wher = n[0][1]
  when = n[0][2]
  at   = n[0][3]
  amou = n[1]

  XX.setdefault(what,{}).setdefault(wher,{}).setdefault(when,{}).setdefault(at,0.0)    
  XX[what][wher][when][at] += amou

添加所有小计(请参见下面的编辑以获取较短版本)

# create the "total" sums in between:
for whatKey in XX:
  for wherKey in XX[whatKey]:
    for whenKey in  XX[whatKey][wherKey]:
      XX[whatKey][wherKey][whenKey]["total"] = 0.0
      for atKey in XX[whatKey][wherKey][whenKey]:
        if atKey != "total":
          XX[whatKey][wherKey][whenKey]["total"] += XX[whatKey][wherKey][whenKey][atKey]

for whatKey in XX:
  for wherKey in XX[whatKey]:
    for whenKey in  XX[whatKey][wherKey]:
      XX[whatKey][wherKey][whenKey]["total"] = 0.0
      for atKey in XX[whatKey][wherKey][whenKey]:
        if atKey != "total":
          XX[whatKey][wherKey][whenKey]["total"] += XX[whatKey][wherKey][whenKey][atKey]

for whatKey in XX:
  for wherKey in XX[whatKey]:
    XX[whatKey][wherKey]["total"] = 0
    for whenKey in  XX[whatKey][wherKey]:
      if whenKey != "total":
        XX[whatKey][wherKey]["total"] += XX[whatKey][wherKey][whenKey]["total"]

for whatKey in XX:
  XX[whatKey]["total"] = 0
  for wherKey in XX[whatKey]:
      if wherKey!= "total":
        XX[whatKey]["total"] += XX[whatKey][wherKey]["total"] 

pprint.pprint(XX)

输出(重新格式化):

{'Fresh Vegetables': 
    {'Hamel': 
        {'2006': {"Bubba's Ebony Corn on the Cob": 317588.95,
                  "Jimmy's Ebony Sweet Peas": 209034.6,
                  "Sue's Ebony Asparagus": 217158.67,
                  'total': 743782.22},
         'total': 743782.22},

     'Mentor': 
         {'2007': {"Bubba's Ebony Corn on the Cob": 343151.59,
                   "Jimmy's Ebony Sweet Peas": 225630.6,
                   "Sue's Ebony Asparagus": 233201.47,
                   'total': 801983.66},
          'total': 801983.66},

     'Sioux Center': 
         {'2007': {"John's Ebony Squash": 401308.01,
                   'total': 401308.01},
          'total': 401308.01},

     'total': 1947073.89}}

编辑避免多个完整的for迭代:

# create the "total" sums in between:
for whatKey in XX: 
  if whatKey == "total":
    continue
  XX[whatKey].setdefault("total",0)

  for wherKey in XX[whatKey]:
    if wherKey == "total":
      continue
    XX[whatKey][wherKey].setdefault("total",0)

    for whenKey in  XX[whatKey][wherKey]: 
      if whenKey == "total":
        continue      
      XX[whatKey][wherKey][whenKey].setdefault("total",0)

      for atKey in XX[whatKey][wherKey][whenKey]:
        if atKey == "total":
          continue

        XX[whatKey][wherKey][whenKey]["total"] += XX[whatKey][wherKey][whenKey][atKey]
        XX[whatKey][wherKey]["total"] += XX[whatKey][wherKey][whenKey][atKey]
        XX[whatKey]["total"] += XX[whatKey][wherKey][whenKey][atKey]

更具可读性的解决方案。你知道吗

这只是词典的主要部分。我想说明的一点是,即使使用简单的递归,也可以实现一些通用的解决方案。你知道吗

但是,对于小计,它需要一些额外的操作,这在本解决方案中尚未涉及。你知道吗

from functools import reduce
import collections

# function to convert a list/tuple to dictionary tree
def totree(keys, value):
  if len(keys) == 1:
    return {keys[0]: value}
  else:
    return {keys[0]: totree(keys[1:], value)}

# function to update nested dictionary
def update(d, u):
    for k, v in u.items():
        if isinstance(v, collections.Mapping):
            d[k] = update(d.get(k, {}), v)
        else:
            d[k] = v
    return d

# the expected dictionary is saved to d
d = reduce(lambda d1, d2: update(d1, d2), map(lambda sub:totree(*sub), x)))

print(d)

这是一种方法:

from collections import defaultdict

d = defaultdict(lambda: defaultdict(lambda: defaultdict(lambda: defaultdict(float))))

for k, v in x:
    d[k[0]][k[1]][k[2]][k[3]] = v

for k1 in d:
    d[k1]['total'] = sum(d[k1][j][k][l] for j in d[k1] for k in d[k1][j] for l in d[k1][j][k])
    for k2 in set(d[k1])-{'total'}:
        d[k1][k2]['total'] = sum(d[k1][k2][k][l] for k in d[k1][k2] for l in d[k1][k2][k])
        for k3 in set(d[k1][k2])-{'total'}:
            d[k1][k2][k3]['total'] = sum(d[k1][k2][k3][l] for l in d[k1][k2][k3])

相关问题 更多 >