Python 使用列表/元组元素作为键创建字典

Python 使用列表/元组元素作为键创建字典,python,python-2.7,dictionary,tuples,Python,Python 2.7,Dictionary,Tuples,我需要生成这样一个字典: { 'newEnv': { 'newProj': { 'newComp': { 'instances': [], 'n_thing': 'newThing' } } } } 从元组中,例如:('newEnv'、'newProj'、'newcompp'、'newThing'),但前提是该元组不存在。所以,我试过这个: myDict = {} (env,proj,com

我需要生成这样一个字典:

{
  'newEnv': {
     'newProj': {
        'newComp': {
           'instances': [],
           'n_thing': 'newThing'
        }
     }
  }
}
从元组中,例如:
('newEnv'、'newProj'、'newcompp'、'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': []}
这很有效,但不确定效率有多高,或者我是否应该这样做。有什么建议吗

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

其中,
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': []})
您可以使用循环(仅使用前3个键,
newThing
不是链中的键):

其中,
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': []})

您可以使用defaultdict中的defaultdict来执行类似的操作,可能稍微简单一点(有关一些讨论,请参阅)

这与martijn的非常类似,只是使用默认功能创建子CT,而不是直接使用
setdefault

这也允许您直接键入

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

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

您可以使用defaultdict的defaultdict做类似的事情,可能稍微简单一点(有关一些讨论,请参阅)

这与martijn的非常类似,只是使用默认功能创建子CT,而不是直接使用
setdefault

这也允许您直接键入

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

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

顺便说一句,你的解决方案无论如何都不坏。顺便说一句,你的解决方案无论如何都不坏。这真是太棒了。
current=myDict.setdefault(key,{})
应该是
current=current.setdefault(key,{}
@MartijnPieters:太酷了!在控制台工作得很好,让我在我的原始脚本中试试。@MartijnPieters:在我的脚本中实现这一点有点问题。我在for循环中运行:
对于get\u all\u队列中的队列:
,对于
实例:[]
bit,我这样做:
myDict[env][proj][comp][instances'].append(queue)
在最后一个
if
语句之后填充“instances”列表。使用新脚本,它不会被追加到列表中,而是只有最后一个。看起来这是因为
internal.update()
?我该如何修复它?干杯!!是的,更新将替换键;使用
internal.setdefault('instances',[]).append(queue)
(并用直接赋值设置另一个键)。这真是太棒了。
current=myDict.setdefault(key,{})
应该是
current=current.setdefault(key,{}
@MartijnPieters:这真的很酷!在控制台中工作得很好,让我试试我的原始脚本。@MartijnPieters:在我的脚本中实现这一点有点问题。我在for循环中运行:
对于get_all_队列中的队列:
对于
实例:[]
位,我这样做:
myDict[env][proj][comp['instances'].append(queue)
在最后一个
if
语句之后填充'instances'列表。使用新脚本,它不会被追加到列表中,而是只有最后一个。看起来这是因为
internal.update()
?如何修复?干杯!!是的,更新将替换键;使用
internal.setdefault('instances',[])。追加(队列)
(并使用直接赋值设置另一个键)。这也是一个很好的解决方案,但我接受了martijn的,因为它与脚本的其余部分配合得很好。感谢您展示了不同的路线。干杯!!这也是一个很好的解决方案,但我接受了martijn的,因为它与脚本的其余部分配合得很好。感谢您展示了不同的路线。干杯!!