我正在对世界杯数据进行一些分析,我发现记录的json文件报废了,
它是一个json对象,您可以检查here
我想获得每场比赛的进球的名称和时间。
我面临的问题是json带有方括号,因为我必须做很多for循环。
我可以避免这样做吗?
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'])
答案 0 :(得分: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
this是从列表或词典中提取必填字段的有用方法。
答案 1 :(得分:1)
我必须完成许多for循环。 我可以避免这样做吗?
您无法完全避免循环,但可以将其隐藏在生成器表达式中:
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
答案 2 :(得分:-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]]}