Как вывести квадратные скобки в объекте json без необходимости делать циклы

1

Я делаю некоторый анализ данных мирового кубка, я нашел отложенный файл записей json,

это объект json, который вы можете проверить здесь.

Я хочу получить имя и время цели для каждого матча.

Проблема, с которой я сталкиваюсь, состоит в том, что json имеет квадратные скобки, из-за этого мне приходится делать много для циклов.

Могу ли я избежать этого?

import requests
import json

r = requests.get('https://raw.githubusercontent.com/openfootball/world-cup.json/master/2018/worldcup.json')
results = json.loads(r.text)

for round in results['rounds']:
    for match in round['matches']:
        if match['score1'] != 0 :
            for goal in match['goals1']:
                print(goal['name'])
                print(goal['minute'])
        if match['score2'] != 0:
            for goal in match['goals2']:
                print(goal['name'])
                print(goal['minute'])
  • 1
    Квадратные скобки образуют массивы, которые должны быть зациклены, если вы хотите, чтобы все элементы
  • 1
    То, что у тебя есть, выглядит хорошо для меня.
Теги:
python-3.x

3 ответа

1
Лучший ответ

Я должен сделать много для циклов. Могу ли я избежать этого?

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

import itertools


def matches():
    m = [round['matches'] for round in results['rounds']]
    yield from itertools.chain(*m)

Тогда вам нужен только один цикл для всех совпадений:

for match in matches():
    your existing code here...

Конечно, вы можете играть в итераторную игру еще на один уровень, а также иметь цели, yield генератором. Это просто пример того, как он может работать.

Обратите внимание, что ваши данные содержат записи, которые имеют score1 > 0 но не ключевые goals1. Вы можете использовать блок try. Тогда вы даже не проверяете счет: просто попробуйте цели, и все готово. Итак, это сводится к:

for match in matches():
    try:
        for goal in match['goals1']:
            print(goal['name'])
            print(goal['minute'])
    except KeyError:
        pass

    try:
        for goal in match['goals2']:
            print(goal['name'])
            print(goal['minute'])
    except KeyError:
        pass
1

Ваш код должен работать нормально. Некоторые из совпадений, хотя и не содержат полей goal которые могут быть исправлены с помощью .get() со значением по умолчанию. Да, нужны циклы, но можно немного упростить:

from operator import itemgetter
import requests
import json

r = requests.get('https://raw.githubusercontent.com/openfootball/world-cup.json/master/2018/worldcup.json')
results = json.loads(r.text)
get_fields = itemgetter('name', 'minute')

for round in results['rounds']:
    for match in round['matches']:
        for goal in match.get('goals1', []) + match.get('goals2', []):
            print(', '.join(map(str, get_fields(goal))))

Это даст вам выход:

Gazinsky, 12
Cheryshev, 43
Dzyuba, 71
Cheryshev, 90
Golovin, 90

itemgetter() - полезный способ извлечения обязательных полей из списка или словаря.

-1

Может быть, ответ не тот, который ищет, нашел схему очень интересной в разборе json и проверке

Попробуйте это https://github.com/keleshev/schema Создайте схему для одного совпадения. Используя схему, вы можете извлечь соответствующие данные.

import requests
import json
from schema import Schema, Use, Or, Optional

r = requests.get('https://raw.githubusercontent.com/openfootball/world-cup.json/master/2018/worldcup.json')
results = json.loads(r.text)

schmeMatch = Schema({
        Optional(Or('goals1','goals2')) : [
            Use(lambda obj: [obj['name'], obj['minute']] )
        ]
    },ignore_extra_keys=True)

for round in results['rounds']:
    for match in round['matches']:
        goals = schmeMatch.validate(match)
        print(goals)

Результат:

{'goals1': [['Gazinsky', 12], ['Cheryshev', 43], ['Dzyuba', 71], ['Cheryshev', 90], ['Golovin', 90]], 'goals2': []}
{'goals1': [], 'goals2': [['Giménez', 89]]}
{'goals1': [['Ronaldo', 4], ['Ronaldo', 44], ['Ronaldo', 88]], 'goals2': [['Costa', 24], ['Costa', 55], ['Nacho', 58]]}
{'goals1': [], 'goals2': [['Bouhaddouz', 90]]}
{'goals1': [['Griezmann', 58], ['Behich', 81]], 'goals2': [['Jedinak', 62]]}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню