Я делаю некоторый анализ данных мирового кубка, я нашел отложенный файл записей 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'])
Я должен сделать много для циклов. Могу ли я избежать этого?
Вы не можете полностью избегать циклов, но вы можете скрыть некоторые из них в выражениях генератора:
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
Ваш код должен работать нормально. Некоторые из совпадений, хотя и не содержат полей 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()
- полезный способ извлечения обязательных полей из списка или словаря.
Может быть, ответ не тот, который ищет, нашел схему очень интересной в разборе 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]]}