I have JSON data that I'm trying to iterate over until the key reaches 'teamName' and the value reaches the team the user inputted. Here's a small section of the JSON data that includes 2 teams:
{'body': [{'conference': 'American Football Conference',
'conferenceAbv': 'AFC',
'currentStreak': {'length': '0', 'result': ''},
'division': 'East',
'espnLogo1': 'https://a.espncdn.com/combiner/i?img=/i/teamlogos/nfl/500/buf.png',
'loss': '0',
'nflComLogo1': 'https://res.cloudinary.com/nflleague/image/private/f_auto/league/giphcy6ie9mxbnldntsf',
'pa': '0',
'pf': '0',
'teamAbv': 'BUF',
'teamCity': 'Buffalo',
'teamID': '4',
'teamName': 'Bills',
'teamStats': {'Defense': {'defTD': '3',
'defensiveInterceptions': '18',
'fumbles': '20',
'fumblesLost': '10',
'fumblesRecovered': '19',
'passDeflections': '79',
'passingTDAllowed': '18',
'passingYardsAllowed': '3342',
'qbHits': '117',
'rushingTDAllowed': '14',
'rushingYardsAllowed': '1880',
'sacks': '54',
'soloTackles': '719',
'tfl': '86',
'totalTackles': '1054'},
'Kicking': {'fgAttempts': '29',
'fgMade': '24',
'fgYds': '0',
'kickYards': '0',
'xpAttempts': '50',
'xpMade': '49'},
'Passing': {'int': '18',
'passAttempts': '579',
'passCompletions': '385',
'passTD': '29',
'passYds': '4306'},
'Punting': {'puntTouchBacks': '3',
'puntYds': '2334',
'punts': '51',
'puntsin20': '24'},
'Receiving': {'recTD': '29',
'recYds': '4306',
'receptions': '385',
'targets': '545'},
'Rushing': {'carries': '512',
'rushTD': '22',
'rushYds': '2212'}},
'tie': '0',
'wins': '0'},
{'conference': 'American Football Conference',
'conferenceAbv': 'AFC',
'currentStreak': {'length': '0', 'result': ''},
'division': 'East',
'espnLogo1': 'https://a.espncdn.com/combiner/i?img=/i/teamlogos/nfl/500/mia.png',
'loss': '0',
'nflComLogo1': 'https://res.cloudinary.com/nflleague/image/private/f_auto/league/lits6p8ycthy9to70bnt',
'pa': '0',
'pf': '0',
'teamAbv': 'MIA',
'teamCity': 'Miami',
'teamID': '20',
'teamName': 'Dolphins',
'teamStats': {'Defense': {'defTD': '4',
'defensiveInterceptions': '15',
'fumbles': '24',
'fumblesLost': '10',
'fumblesRecovered': '25',
'passDeflections': '81',
'passingTDAllowed': '27',
'passingYardsAllowed': '3761',
'qbHits': '140',
'rushingTDAllowed': '15',
'rushingYardsAllowed': '1650',
'sacks': '56',
'soloTackles': '711',
'tfl': '79',
'totalTackles': '1088'},
'Kicking': {'fgAttempts': '28',
'fgMade': '24',
'fgYds': '0',
'kickYards': '0',
'xpAttempts': '59',
'xpMade': '58'},
'Passing': {'int': '15',
'passAttempts': '566',
'passCompletions': '393',
'passTD': '30',
'passYds': '4698'},
'Punting': {'puntTouchBacks': '3',
'puntYds': '2424',
'punts': '53',
'puntsin20': '20'},
'Receiving': {'recTD': '30',
'recYds': '4698',
'receptions': '393',
'targets': '549'},
'Rushing': {'carries': '456',
'rushTD': '27',
'rushYds': '2308'}},
'tie': '0',
'wins': '0'},
Here's what I've tried so far:
data = response.json()
userinput_team = input('Enter the team name')
userteam = str(userinput_team)
def defense(i):
for key in data["body"][i]:
value = data["body"][i][key]
if key == 'teamName' and value == userteam:
userdefense = data['body'][i]['teamStats']['Defense']
print(f"Here are the defensive stats for the {value}:\n{userdefense}")
return
else:
return defense(i+1)
defense(0)
Without the else statement if I input Bills for userteam, since i is already 0 the code works fine and the output is:
Here are the defensive stats for the Bills:
{'fumblesLost': '10', 'defTD': '3', 'fumbles': '20', 'fumblesRecovered': '19', 'soloTackles': '719', 'qbHits': '117', 'passingTDAllowed': '18', 'passDeflections': '79', 'passingYardsAllowed': '3342', 'totalTackles': '1054', 'defensiveInterceptions': '18', 'tfl': '86', 'rushingYardsAllowed': '1880', 'sacks': '54', 'rushingTDAllowed': '14'}
The problem is iterating through the data and stopping once the key reaches 'teamName' and the value reaches the team the user inputted. I figured with the else statement that the function would call itself if 'teamName' and userteam weren't found in the first index 0 and would just increment by 1 until they were found but all I get is IndexError: list index out of range and I'm not sure what to do.
I know I can just do something like:
data = response.json()
userinput_team = input('Enter the team name')
userteam = str(userinput_team)
Bills = 0
Dolphins = 1
userdefense_Bills = data['body'][Bills]['teamStats']['Defense']
userdefense_Dolphins = data['body'][Dolphins]['teamStats']['Defense']
if userteam == 'Bills':
print(userdefense_Bills)
elif userteam == 'Dolphins':
print(userdefense_Dolphins)
else:
print('Team not found')
but this just seems counterintuitive considering the full JSON data consists of 32 total teams. I'm new to Python so I don't know if I'm missing some small detail. I've searched for similar questions but they're either in a different language or only on one level JSON.
Since you just need the first match, you can do this in a single expression using next()
:
userinput_team = 'Bills'
team_defense = next(
(
item['teamStats']['Defense']
for item in data['body']
if item['teamName'] == userinput_team
),
None. # <- this can be any default value you want for unknown team
)
Which will give you
{'defTD': '3',
'defensiveInterceptions': '18',
'fumbles': '20',
'fumblesLost': '10',
'fumblesRecovered': '19',
'passDeflections': '79',
'passingTDAllowed': '18',
'passingYardsAllowed': '3342',
'qbHits': '117',
'rushingTDAllowed': '14',
'rushingYardsAllowed': '1880',
'sacks': '54',
'soloTackles': '719',
'tfl': '86',
'totalTackles': '1054'}
if the team is found, otherwise None
.