Ошибка типа: строковые индексы должны быть целыми числами и другими с коллекциями JSON

#python #json #collections

#python #json #Коллекции

Вопрос:

Загружая коллекции json в Python, я обнаружил ряд проблем, которые возникают, когда в коллекции может быть 0, 1 или более элементов, и python переключается между object not found, объектом dictionary и списком словарей. Оглядываясь вокруг, я видел код, пытающийся справиться с этим различными способами, но на самом деле не нашел общего решения того, что, как я полагаю, должно быть довольно распространенной проблемой при наличии переменного количества элементов.

Существующий совет , казалось , заканчивался на » если » … elif … еще обработка объекта json, но это действительно грязно делать каждый раз, когда вы обрабатываете объект, потому что вы заканчиваете с кодом для обработки объекта в нескольких ветвях кода.

Комментарии:

1. Совет, вероятно, правильный. API не должен быть разработан для предоставления разных структур для одного и того же типа запроса. РЕДАКТИРОВАТЬ: ну, на самом деле, это файл, поэтому все, что создает файл, не должно делать это таким образом.

2. @roganjosh — если бы у вас был полный контроль над всеми частями кода, это было бы правильно. В этом случае этот файл создается широко используемой библиотекой Newtonsoft json.

3. Если вы сами отвечаете на свой вопрос, это совершенно нормально, но, пожалуйста, постарайтесь сохранить шаблон вопроса в вопросе, а затем ответить на вопрос в разделе ответов.

Ответ №1:

После небольшого размышления я придумал следующий шаблон, который разрешил это и, похоже, надежно работает, если в коллекции 0, 1 или много элементов.

 def node_list(d, k) :
    """
    handle a collection node in a json object by returning:
        an empty list if there are no child nodes at d[k],
        or a list with 1 dictionary entry if there is one child node at d[k]
        or a list of dictionaries if there are multiple child nodes at d[k]
    """ 
    if d is None : raise Exception("d is None")
    if type(d) is not dict : raise Exception("d is not a dict")
    if d.get(k) is None : return []
    if type(d.get(k)) is dict : return [d.get(k)]
    if type(d.get(k)) is not list : raise Exception("d[k] is not a dict or list")
    return d.get(k)
  

Вызов для обработки коллекции json теперь выглядит следующим образом:

 import json
root = json.load(open(file,'r', encoding='utf-8-sig'))
for item in node_list(root,'Item') :
   # code to handle each item here
   pass
  

Теперь, если есть 0,1 или много элементов, я получаю соответствующий список с 0, 1 или многими элементами в нем.