TypeError: first argument must be callable, defaultdict

廉价感情. 提交于 2019-12-20 04:03:12

问题


The error comes from publishDB = defaultdict(defaultdict({})) I want to make a database like {subject1:{student_id:{assignemt1:marks, assignment2:marks,finals:marks}} , {student_id:{assignemt1:marks, assignment2:marks,finals:marks}}, subject2:{student_id:{assignemt1:marks, assignment2:marks,finals:marks}} , {student_id:{assignemt1:marks, assignment2:marks,finals:marks}}}. I was trying to populate it as DB[math][10001] = a dict and later read out as d = DB[math][10001]. Since, I am on my office computer I can not try different module.

Am I on right track to do so?


回答1:


Such a nested dict structure can be achieved using a recursive defaultdict "tree":

def tree(): 
    return defaultdict(tree)

publishDB = tree()

At each level, the defaultdicts are instantiated with tree which is a zero-argument callable, as required. Then you can simply assign marks:

publishDB[subject][student][assignment] = mark



回答2:


defaultdict() requires that its first argument be callable: it must be a class that you want an instance of, or a function that returns an instance.

defaultdict({}) has an empty dictionary, which is not callable.

You likely want defaultdict(dict), as dict is a class that returns a dictionary when instantiated (called).

But that still doesn't solve the problem... just moves it to a different level. The outer defaultdict(...) in defaultdict(defaultdict(dict)) has the exact same issue because defaultdict(dict) isn't callable.

You can use a lambda expression to solve this, creating a one-line function that, when called, creates a defaultdict(dict):

 defaultdict(lambda: defaultdict(dict))

You could also use the lambda at the lower level if you wanted:

defaultdict(lambda: defaultdict(lambda: {}))


来源:https://stackoverflow.com/questions/40712753/typeerror-first-argument-must-be-callable-defaultdict

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!