【问题标题】:Creating dictionary using list/tuple elements as key使用列表/元组元素作为键创建字典
【发布时间】:2014-01-28 06:50:16
【问题描述】:

我需要生成这样的字典:

{
  'newEnv': {
     'newProj': {
        'newComp': {
           'instances': [],
           'n_thing': 'newThing'
        }
     }
  }
}

来自一个元组,像这样:('newEnv','newProj','newComp','newThing') 但前提是它不存在。所以,我尝试了这个:

myDict = {}
(env,proj,comp,thing) = ('newEnv','newProj','newComp','newThing')

if env not in myDict:
    myDict[env] = {}
if proj not in myDict[env]:
    myDict[env][proj] = {}
if comp not in myDict[env][proj]:
    myDict[env][proj][comp] = {'n_thing': thing, 'instances': []}

这非常有效,但不确定它的效率如何,或者我是否应该这样做。有什么建议)??

【问题讨论】:

  • 顺便说一句,你的解决方案无论如何都不错。

标签: python python-2.7 dictionary tuples


【解决方案1】:

您可以使用循环(只有前 3 个键,newThing 不是链中的键):

myDict = {}
path = ('newEnv','newProj','newComp')
current = myDict
for key in path:
    current = current.setdefault(key, {})

current 最终成为最里面的字典,让您可以在其中设置 'n_thing''instances' 键。

您可以使用reduce() 将其折叠成单行:

myDict = {}
path = ('newEnv','newProj','newComp')
reduce(lambda d, k: d.setdefault(k, {}), path, myDict)

reduce 调用返回最里面的字典,因此您可以使用它来分配最终值:

myDict = {}
path = ('newEnv','newProj','newComp')
inner = reduce(lambda d, k: d.setdefault(k, {}), path, myDict)
inner.update({'n_thing': 'newThing', 'instances': []})

【讨论】:

  • 这真是太棒了。
  • current = myDict.setdefault(key, {}) 应该是current = current.setdefault(key, {}
  • @MartijnPieters:这真的很酷!在控制台中工作得很好,让我试试我的原始脚本。
  • @MartijnPieters:在我的脚本中实现这个有一个小问题。我在 for 循环中运行它:for queue in get_all_queues:'instances': [] 位,我这样做:myDict[env][proj][comp]['instances'].append(queue) 在最后一个 if 语句之后填充“实例”列表。使用新脚本,它不会被附加到列表中,而只有最后一个。好像是因为inner.update()?我该如何解决?干杯!!
  • 是的,更新将替换密钥;使用inner.setdefault('instances', []).append(queue)(并直接分配另一个键)。
【解决方案2】:

您可以使用 defaultdicts 的 defaultdict 做类似的事情,也许稍微简单一些(有关讨论,请参阅 defaultdict of defaultdict, nested

tree = lambda: defaultdict(tree)

base = tree()
for x in mytuple[:-2]:
    base = base[x]
base[x] = mytuple[-1]

这与martijn 的非常相似,只是使用默认功能来创建subdicts,而不是直接使用setdefault

这也可以让你直接输入

myDict[env][proj][comp].setdefault('instances', list()).append(queue)

如果那是您真正想要的。 (不幸的是,没有办法删除 setdefault;毕竟,我不提前知道你想要一个列表还是字典。你只有一个默认值)....

【讨论】:

  • 这也是一个不错的解决方案,但我接受了 martijn 的解决方案,因为它与脚本的其余部分配合得很好。感谢您展示不同的路线。干杯!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-10
  • 2020-09-25
  • 1970-01-01
  • 2023-02-05
  • 1970-01-01
  • 1970-01-01
  • 2010-11-28
相关资源
最近更新 更多