Ошибка типа: строковые индексы должны быть целыми числами (Python)

#python #json #mongodb

#python #json #mongodb

Вопрос:

Я получаю TypeError: string indices must be integers при попытке выполнить итерацию по JSON с помощью приведенного ниже кода. Я пытался найти ответ в нескольких других потоках, но безуспешно.

Это начало моего JSON:

     '?xml': {
    '@version': '1.0',
    '@encoding': 'ISO-8859-1'
},
'scores': {
    '@sport': 'soccer',
    '@updated': '28.12.2020 04:49:21',
    'category': [{
        '@name': 'Africa: Caf Champions League - Qualification',
        '@gid': '19297',
        '@id': '1513',
        '@file_group': 'africa',
        '@iscup': 'False',
        'matches': {
            '@date': 'Dec 28',
            '@formatted_date': '28.12.2020',
            'match': {
                '@status': '19:45',
                '@timer': '',
                '@date': 'Dec 28',
                '@formatted_date': '28.12.2020',
                '@time': '19:45',
                '@commentary_available': '1513',
                '@venue': '',
                '@v': '0',
                '@static_id': '2938748',
                '@fix_id': '3445943',
                '@id': '3792777',
                'localteam': {
                    '@name': 'MC Alger',
                    '@goals': '?',
                    '@id': '5784'
                },
                'visitorteam': {
                    '@name': 'Sfaxien',
                    '@goals': '?',
                    '@id': '16927'
                },
                'events': None,
 

Это код Python, который я запускаю:

 import urllib.request, json, random, pymongo
from pymongo import MongoClient

client = MongoClient('mongodb://localhost:27017/')
db = client["gameDB"]
collection = db["players"]

with urllib.request.urlopen("https://www.myjsonfile.com") as url:
    data = json.loads(url.read().decode())
    #print(data)

league_id = 0
league_name = ''
match_id = 0
match_name = ''

for league in data['scores']['category']:
    league_id = league['@id']
    league_name = league['@name']

    
    
    
    for match in league['matches']['match']:
        
        match_id = match['@static_id']
        match_name = match['localteam']['@name']

        print({"{} {} {} {}".format(league_id, league_name, match_id, match_name)})
 

и это ошибка, которую я получаю:

     Traceback (most recent call last):
  File "/Users/testScript.py", line 30, in <module>
    match_id = match['@static_id']
TypeError: string indices must be integers
 

Причина, по которой я в замешательстве, заключается в том, что он работает с некоторым кодом, но не с другим, и код выглядит так же, как:

 '@static_id': '2938748',
 

Есть идеи?

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

1. Кажется, что в случае, когда выдается ошибка, «match» — это строка, возможно, добавьте перед ней печать (совпадение) и опубликуйте ту часть json, где это происходит.

2. match['@static_id'] работает только тогда, когда match это dict, а не список. Но эта ошибка говорит вам, что match это список. Вам нужно покопаться в этом и отладить его, использовать инструкции печати, IDE, выяснить, почему.

3. Пожалуйста, прочтите о том, как отлаживать небольшие программы . Вы также можете использовать Python-Tutor , который помогает визуализировать выполнение кода шаг за шагом.

Ответ №1:

Внимательно посмотрите на то, что вы на самом деле перебираете здесь:

 for match in league['matches']['match']:
    match_id = match['@static_id']
    match_name = match['localteam']['@name']
 

match в данном случае это ключи match dict , то '@status' есть , '@timer' , и так далее, которые являются строками. Вы можете получить доступ к символам строки, используя идентификаторы в Pyhton, т.е. 'example'[1] # 'x' . Вот откуда приходит сообщение об ошибке. Вместо этого вы хотите следующее:

 match = league['matches']['match']:
match_id = match['@static_id']
match_name = match['localteam']['@name']
 

Ответ №2:

 for match in league['matches']['match']:
    
    match_id = match['@static_id']
    match_name = match['localteam']['@name']
 

Вы перебираете dict (совпадение), как список. Вам нужно перебирать его, как словарь:

 for key, value in data.items():
    print(key, value)