如何在不需要执行循环的情况下在json对象中转储方括号

时间:2018-07-04 18:53:41

标签: python json python-3.x

我正在对世界杯数据进行一些分析,我发现记录的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'])

3 个答案:

答案 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]]}