【问题标题】:how to get all the keys in a 2d dict python如何获取 2d dict python 中的所有键
【发布时间】:2012-10-18 17:08:11
【问题描述】:

我有一本形式的字典:

d = {123:{2:1,3:1}, 124:{3:1}, 125:{2:1},126:{1:1}}

那么,让我们看看 2nd degree key..

123--> 2,3
124--> 3
125--> 2
126--> 1

所以唯一的二阶键的总数是:

1,2,3

现在,我想将这个字典修改为

 d = {123:{1:0,2:1,3:1}, 124:{1:0,2:0,3:1}, 125:{1:0,2:1,3:0},126:{1:1,2:0,3:0}}

所以基本上所有的二阶键都不存在于特定的二维字典中。添加值为 0 的键。

pythonic 的方法是什么? 谢谢

【问题讨论】:

    标签: python dictionary


    【解决方案1】:
    keyset = set()
    for k in d:
        keyset.update(d[k])
    
    for k in d:
        for kk in keyset:
            d[k].setdefault(kk, 0)
    

    【讨论】:

    • +1。简单易读。一个很好的提醒,不要在一条线上做太多。
    【解决方案2】:
    In [25]: d = {123:{2:1,3:1}, 124:{3:1}, 125:{2:1},126:{1:1}}
    
    In [26]: se=set(y for x in d for y in d[x])
    
    In [27]: for x in d:
        foo=se.difference(d[x])
        d[x].update(dict(zip(foo,[0]*len(foo))))
       ....:     
       ....:     
    
    In [30]: d
    Out[30]: 
    {123: {1: 0, 2: 1, 3: 1},
     124: {1: 0, 2: 0, 3: 1},
     125: {1: 0, 2: 1, 3: 0},
     126: {1: 1, 2: 0, 3: 0}}
    

    这里使用 set Difference 来获取丢失的键,然后 update() dict:

    In [39]: for x in d:
        foo=se.difference(d[x])
        print foo                # missing keys per dict
    set([1])
    set([1, 2])
    set([1, 3])
    set([2, 3])
    

    【讨论】:

    • 无需将zip 的结果转换为dictupdate 可以处理两个项目元组的列表。
    • 在我看来,如果使用set(key2 for key,value in d.iteritems() for key2 in value) 会更加Pythonic。此外,没有必要在d[x].update(dict(zip(foo,[0]*len(foo)))) 中构造dict,因为update 可以只使用迭代器,所以d[x].update(zip(foo,[0]*len(foo))) 可以,同样,如果iteritems()d[x],这里的d[x] 也可以替换为value用过。
    【解决方案3】:

    我喜欢 Ashwini Chaudhary 的解决方案。

    我对其进行了编辑,以将 cmets 中的所有建议与其他细微更改结合起来,以使其看起来像我喜欢的那样:

    已编辑(将 Steven Rumbalski 的建议纳入此答案)。

    all_second_keys = set(key for value in d.itervalues() for key in value)
    
    for value in d.itervalues():
        value.update((key,0) for key in all_second_keys if key not in value)
    

    【讨论】:

    • 我会把第一行改成all_second_keys = set(key for value in d.itervalues() for key in value)
    • 第二行至:for value in d.itervalues(): value.update((key,0) for key in all_second_keys.difference(value))
    • @StevenRumbalski 谢谢!我更新了答案。我只是没有将...for key in all_second_keys if key not in value 更改为for key in all_second_keys.difference(value)。它们的时间复杂度是相同的,但我更喜欢我在答案中留下的方式。
    【解决方案4】:
    import operator
    
    second_order_keys = reduce(operator.__or__,
                               (set(v.iterkeys()) for v in d.itervalues()))
    for v in d.itervalues():
        for k in second_order_keys:
            v.setdefault(k, 0)
    

    或者,在 Python 3 中:

    from functools import reduce
    import operator
    
    second_order_keys = reduce(operator.__or__,
                               (v.keys() for v in d.values()))
    for v in d.values():
        for k in second_order_keys:
            v.setdefault(k, 0)
    

    【讨论】:

    • 我必须阅读您对reduce 的使用几次才能理解它。 second_order_keys = set(k for v in d.itervalues() for k in v) 对我来说更简单。
    • @StevenRumbalski :) 我仍然无法理解 reduce 的作用以及为什么需要 or 运算符。
    • @StevenRumbalski 一分钟后才知道。确实很复杂!
    • @ovgolovin:有更多功能背景的人(不是我)很清楚。
    • @StevenRumbalski:我实际上同意,但这是我想到的第一个版本,当其他人发布了更好的解决方案时,我决定保持原样。 FP恰好是我日常工作的主要部分:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-27
    • 1970-01-01
    • 1970-01-01
    • 2020-06-17
    • 2018-10-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多