【问题标题】:create nested dictionary one liner创建嵌套字典一层
【发布时间】:2018-05-10 19:06:19
【问题描述】:

您好,我有三个列表,我想使用一行创建一个三层嵌套字典。

即,

l1 = ['a','b']
l2 = ['1', '2', '3']
l3 = ['d','e']

我想创建以下嵌套字典:

nd = {'a':{'1':{'d':0},{'e':0},'2':{'d':0},{'e':0},'3':{'d':0},{'e':0},'b':'a':{'1':{'d':0},{'e':0},'2':{'d':0},{'e':0},'3':{'d':0},{'e':0}}

我尝试使用 zip 执行外循环并添加列表,但元素被替换。即,这不起作用:

nd = {i:{j:{k:[]}} for i in zip(l1,l2,l3)}

【问题讨论】:

    标签: python dictionary


    【解决方案1】:

    zip 不会在这里做。 zip 连续遍历所有 3 个列表。您需要的是产品——实际上是 3 个嵌套循环。您可以以牺牲一些可读性为代价将其扁平化为单个字典理解。

    >>> {i : {j : {k : 0 for k in l3} for j in l2} for i in l1}
    

    {'a': {'1': {'d': 0, 'e': 0}, 
           '2': {'d': 0, 'e': 0}, 
           '3': {'d': 0, 'e': 0}},
     'b': {'1': {'d': 0, 'e': 0}, 
           '2': {'d': 0, 'e': 0}, 
           '3': {'d': 0, 'e': 0}}
    }
    

    或者,如果您想要最底层的单键字典列表(如您的 o/p 建议的那样),

    >>> {i : {j : [{k : 0} for k in l3] for j in l2} for i in l1}
    

    {'a': {'1': [{'d': 0}, {'e': 0}],
           '2': [{'d': 0}, {'e': 0}],
           '3': [{'d': 0}, {'e': 0}]},
     'b': {'1': [{'d': 0}, {'e': 0}],
           '2': [{'d': 0}, {'e': 0}],
           '3': [{'d': 0}, {'e': 0}]}
    }
    

    【讨论】:

      【解决方案2】:

      您还可以通过更简单的循环使用递归:

      l1 = ['a','b']
      l2 = ['1', '2', '3']
      l3 = ['d','e']
      def combinations(d):
        return {i:combinations(d[1:]) if d[1:] else 0 for i in d[0]}
      
      print(combinations([l1, l2, l3]))
      

      输出:

      {'b': {'1': {'d': 0, 'e': 0}, '2': {'d': 0, 'e': 0}, '3': {'d': 0, 'e': 0}}, 'a': {'1': {'d': 0, 'e': 0}, '2': {'d': 0, 'e': 0}, '3': {'d': 0, 'e': 0}}}
      

      编辑:真正的单线:

      print((lambda d:{i:combination(d[1:]) if d[1:] else 0 for i in d[0]})([l1, l2, l3]))
      

      输出:

      {'b': {'1': {'d': 0, 'e': 0}, '2': {'d': 0, 'e': 0}, '3': {'d': 0, 'e': 0}}, 'a': {'1': {'d': 0, 'e': 0}, '2': {'d': 0, 'e': 0}, '3': {'d': 0, 'e': 0}}}
      

      【讨论】:

      • 不错的替代品,但正如标题所要求的那样,这不是单行(好吧,您可以将 return 向上移动一行,但仍然必须调用该函数)。
      • @cᴏʟᴅsᴘᴇᴇᴅ 是的,但是,lambda 也可以使用(尽管它不如预定义函数干净)。请查看我最近的编辑。
      • (重新:编辑)命名 lambdas 是错误的形式;您不妨将它们提升为成熟的功能。如果你坚持使用 lambda,我可以推荐print((lambda d:{i:combination(d[1:]) if d[1:] else 0 for i in d[0]})([l1, l2, l3]))
      • @cᴏʟᴅsᴘᴇᴇᴅ 我不坚持,但是,这是使用函数产生“单行”结果的唯一方法。
      猜你喜欢
      • 1970-01-01
      • 2016-05-06
      • 1970-01-01
      • 2023-01-18
      • 1970-01-01
      • 2021-04-04
      • 1970-01-01
      • 2018-11-09
      • 2018-03-27
      相关资源
      最近更新 更多