使用`defaultdicts`的Python程序无法按预期工作

时间:2014-07-21 01:26:37

标签: python

预期结果:

main_dict = { 
                'a':
                    { 0: 'Letter a',
                      1: 'Letter a',
                      2: 'Letter a',},

                'b':
                    { 0: 'Letter b',
                      1: 'Letter b',
                      2: 'Letter b',},

                'c':
                    { 0: 'Letter c',
                      1: 'Letter c',
                      2: 'Letter c',}

             }

我的程序,版本1;预期的结果是输出。

# my_program.py
def fill_dict(a_dict, a_key):

    if not a_dict.has_key(a_key):
        a_dict[a_key] = {}

    for i in xrange(3):
        a_dict[a_key][i] = 'Letter {}'.format(a_key)

def main():
    main_dict = {}

    a_list = ['a', 'b', 'c']

    for item in a_list:
        fill_dict(main_dict, item)

if __name__ == '__main__':
    main()

使用defaultdicts重构程序;结果是main_dict = {}

# defaultdict_test.py
import collections

def fill_dict(a_dict, a_key):

    a_dict = collections.defaultdict(dict)

    for i in xrange(3):
        a_dict[a_key][i] = 'Letter {}'.format(a_key)

def main():
    main_dict = {}

    a_list = ['a', 'b', 'c']

    for item in a_list:
        fill_dict(main_dict, item)

if __name__ == '__main__':
    main()

关于我做错了什么的指示?感谢。

2 个答案:

答案 0 :(得分:2)

您正在将main_dict传递给fill_dict,然后将新的defaultdict分配给本地变量a_dict。你永远不会把这个值传回去。

在你的程序中,你不会重新分配本地,所以当你在a_dict上调用方法时,你正在修改传入的值,即main中的main_dict值。

在重新分配和用方法变异之间的这种区别是微妙但重要的。本文详细介绍了名称,值及其互动:Facts and myths about Python names and values

答案 1 :(得分:0)

指针:

  1. 在第一个版本中使用in vs has_key。方法has_key已在Python 3中进行了描述和删除
  2. a_dict = collections.defaultdict(dict)
  3. 移除fill_dict
  4. main_dict = {}
  5. 中将main_dict = collections.defaultdict(dict)更改为main

    完成!

    import collections
    
    def fill_dict(a_dict, a_key):
        for i in xrange(3):
            a_dict[a_key][i] = 'Letter {}'.format(a_key)        
    
    def main():
        main_dict = collections.defaultdict(dict)
    
        a_list = ['a', 'b', 'c']
    
        for item in a_list:
            fill_dict(main_dict, item)
    

    最终指针:了解列表,设置和词典理解。您可以在一行中执行此数据结构:

    >>> {c:{i: 'Letter {}'.format(c) for i in range(3)} for c in 'abc'}
    {'a': {0: 'Letter a', 1: 'Letter a', 2: 'Letter a'}, 'c': {0: 'Letter c', 1: 'Letter c', 2: 'Letter c'}, 'b': {0: 'Letter b', 1: 'Letter b', 2: 'Letter b'}}
    

    如果你看一下它 - 它几乎是你所拥有的你想要的结果的版本,如果你这样格式化:

    dict_you_want={
                       c:
                           {  i: 'Letter {}'.format(c) 
                                for i in range(3)  }   # , 
    
                          for c in 'abc'
                  }
    

    将像我在那里一样执行...