TypeError: первый аргумент должен быть вызываемым, defaultdict

Ошибка возникает из-за publishDB = defaultdict(defaultdict({})), я хочу создать базу данных, подобную {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}}}. Я пытался заполнить его как DB[math][10001] = a dict, а позже прочитать как d = DB[math][10001]. Так как я нахожусь на своем офисном компьютере, я не могу попробовать другой модуль.

Я на правильном пути?


person Varmakochin    schedule 21.11.2016    source источник
comment
попробуйте dict вместо {} может быть?   -  person Elliot Roberts    schedule 21.11.2016


Ответы (2)


Такая вложенная структура dict может быть получена с помощью рекурсивного defaultdict "дерева":

def tree(): 
    return defaultdict(tree)

publishDB = tree()

На каждом уровне defaultdicts создаются с помощью tree, который при необходимости вызывается без аргументов. Затем вы можете просто назначать отметки:

publishDB[subject][student][assignment] = mark
person schwobaseggl    schedule 21.11.2016

defaultdict() требует, чтобы его первый аргумент был вызываемым: это должен быть класс, экземпляр которого вам нужен, или функция, возвращающая экземпляр.

defaultdict({}) имеет пустой словарь, который нельзя вызвать.

Вероятно, вам нужен defaultdict(dict), так как dict — это класс, который возвращает словарь при создании экземпляра (вызове).

Но это все равно не решает проблему... просто переводит ее на другой уровень. Внешний defaultdict(...) в defaultdict(defaultdict(dict)) имеет ту же проблему, потому что defaultdict(dict) не вызывается.

Вы можете использовать выражение lambda, чтобы решить эту проблему, создав однострочную функцию, которая при вызове создает defaultdict(dict):

 defaultdict(lambda: defaultdict(dict))

Вы также можете использовать лямбду на нижнем уровне, если хотите:

defaultdict(lambda: defaultdict(lambda: {}))
person kindall    schedule 21.11.2016
comment
это часть проблемы, но не все. это тоже не работает: publishDB = defaultdict(defaultdict(dict)), потому что defaultdict(dict) передается в качестве первого аргумента для внешнего dict, и его также нельзя вызывать. - person Elliot Roberts; 21.11.2016