简体   繁体   English

Python 嵌套字典追加 - 使用 defaultdict(lambda: defaultdict(set)) 解决

[英]Python Nested Dictionary append - Solved with defaultdict(lambda: defaultdict(set))

done this millions of times in other languages by python method for this is escaping me.通过 python 方法在其他语言中完成了数百万次,因为这让我无法理解。

Basically reading some data from database.基本上是从数据库中读取一些数据。 Includes data like ID, Fruits, Colors, Name包括 ID、水果、颜色、名称等数据

I need to create an object / dictionary key on Name.我需要在名称上创建一个对象/字典键。 Name then holds lists / dictionaries of Fruits and Colors.然后名称包含水果和颜色的列表/字典。

{"greenhouse1": {"fruits": {"apples", "oranges"}
                {"colors": {"red","orange"}}

I'm iterating through the db by row and the Name key will appear more than once.我逐行遍历数据库,名称键将出现多次。 When it does fruits or colors may already be populated and need to append.当它执行时,水果或颜色可能已经填充并需要附加。

namedict = {}
db_rows = execute_query(cursor, args.store_proc)

for row in db_rows:
  db_name = row.id
  db_fruit = row.fruit
  db_color = row.color
  if db_name in namedict:
    namedict[db_name]["fruits"].append(db_fruit)
    namedict[db_name]["color"].append(db_color)
  else:
    namedict[db_name]["fruits"] = [db_fruit]
    namedict[db_name]["color"] = [db_color]

collections.defaultdict is your friend: If you access a new key of a defaultdict, it is automatically initialised with the provided function ( list or set in this case). collections.defaultdict是您的朋友:如果您访问 defaultdict 的新键,它会使用提供的函数(在本例中为listset )自动初始化。 Because you want a dictionary (eg "greenhouse1") of dictionaries ("fruits", "colors") with lists as values (separate fruits and colors), we need a nested defaultdict.因为你想要一个包含列表作为值(分开的水果和颜色)的字典(“fruits”、“colors”)的字典(例如“greenhouse1”),所以我们需要一个嵌套的 defaultdict。 The following should work:以下应该有效:

from collections import defaultdict

db = defaultdict(lambda: defaultdict(list))  # alternative: set instead of list
db['greenhouse1']['fruits'].append('apples')  # use `add` for sets
db['greenhouse1']['fruits'].append('oranges')
db['greenhouse1']['colors'] = ["red", "orange"]

db['greenhouse2']['fruits'].append('banana')

print(db)
# defaultdict(<function __main__.<lambda>()>,
#             {'greenhouse1': defaultdict(list,
#                          {'fruits': ['apples', 'oranges'],
#                           'colors': ['red', 'orange']}),
#              'greenhouse2': defaultdict(list, {'fruits': ['banana']})})

A defaultdict works like a regular dict, so don't get confused with the strange looking output. defaultdict的工作方式与常规 dict 类似,因此不要对奇怪的输出感到困惑。 Eg to access the fruits of greenhouse1 you can simply write db['greenhouse1']['fruits'] and you get back a list (or set).例如,要访问温室 1 的果实,您可以简单地编写db['greenhouse1']['fruits']并返回一个列表(或集合)。

First, you need quotes around fruits and color in the dictionary keys.首先,您需要在字典键中为fruitscolor加上引号。

Second, you can't create a nested dictionary element until you create the dictionary.其次,在创建字典之前,您无法创建嵌套字典元素。

You can simplify the code by using collections.defaultdict .您可以使用collections.defaultdict来简化代码。 Since you want nested dictionaries, you need nested defaultdicts.由于您需要嵌套字典,因此需要嵌套默认字典。

from collections import defaultdict

namedict = defaultdict(lambda: defaultdict(set))

for row in db_rows:
    namedict[row.id]['fruits'].add(row.fruit)
    namedict[row.id]['colors'].add(row.color)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM