python - 使用 python 与 JSON 交互的更快方法
问题描述
我刚刚开始练习使用 JSON 文件并与 API 进行交互,在这种情况下,我正在与游戏的 API(Riot API)进行交互。我有一个带有我的比赛历史的 JSON,它看起来像这样(我刚刚复制了 3 场比赛,真实文件更长):
{
"matches": [
{
"platformId": "EUW1",
"gameId": 4733037811,
"champion": 111,
"queue": 420,
"season": 13,
"timestamp": 1596031907965,
"role": "DUO_SUPPORT",
"lane": "BOTTOM"
},
{
"platformId": "EUW1",
"gameId": 4732867446,
"champion": 25,
"queue": 420,
"season": 13,
"timestamp": 1596022617021,
"role": "DUO_SUPPORT",
"lane": "BOTTOM"
},
{
"platformId": "EUW1",
"gameId": 4732833555,
"champion": 111,
"queue": 420,
"season": 13,
"timestamp": 1596020420595,
"role": "DUO_SUPPORT",
"lane": "BOTTOM"
},
{
"platformId": "EUW1",
"gameId": 4731796980,
"champion": 53,
"queue": 420,
"season": 13,
"timestamp": 1595967793994,
"role": "DUO_SUPPORT",
"lane": "BOTTOM"
},
但是,我想要更多关于我的游戏的信息,我需要使用该游戏搜索特定游戏。包含特定游戏信息的 JSON 如下所示(由于 JSON 的大小,我删除了每个玩家的一些不必要的统计信息):
{
"gameId": 4733037811,
"platformId": "EUW1",
"gameCreation": 1596031907965,
"gameDuration": 1624,
"queueId": 420,
"mapId": 11,
"seasonId": 13,
"gameVersion": "10.15.330.344",
"gameMode": "CLASSIC",
"gameType": "MATCHED_GAME",
"participants": [
{
"participantId": 1,
"teamId": 100,
"championId": 61,
"stats": {
"participantId": 1,
"win": true,
"kills": 14,
"deaths": 0,
"assists": 7,
"totalDamageDealt": 167616,
"magicDamageDealt": 149177,
"physicalDamageDealt": 10740,
"trueDamageDealt": 7698,
"totalDamageDealtToChampions": 22933,
"magicDamageDealtToChampions": 21067,
"physicalDamageDealtToChampions": 1208,
},
{
"participantId": 2,
"teamId": 100,
"championId": 21,
"stats": {
"participantId": 2,
"win": true,
"kills": 2,
"deaths": 3,
"assists": 6,
"totalHeal": 1742,
"totalUnitsHealed": 2,
"damageSelfMitigated": 7396,
"damageDealtToObjectives": 19128,
"damageDealtToTurrets": 4817,
},
{
"participantId": 3,
"teamId": 100,
"championId": 432,
"stats": {
"participantId": 3,
"win": true,
"kills": 1,
"deaths": 4,
"assists": 14,
"largestKillingSpree": 0,
"trueDamageDealt": 3202,
"largestCriticalStrike": 0,
"totalDamageDealtToChampions": 7395,
"magicDamageDealtToChampions": 5286,
{
"participantId": 4,
"teamId": 100,
"championId": 122,
"stats": {
"participantId": 4,
"win": true,
"kills": 7,
"deaths": 2,
"assists": 6,
"largestKillingSpree": 5,
"largestMultiKill": 2,
"killingSprees": 1,
{
"participantId": 5,
"teamId": 100,
"championId": 79,
"stats": {
"participantId": 5,
"win": true,
"kills": 1,
"deaths": 3,
"assists": 9,
"largestKillingSpree": 0,
"largestMultiKill": 1,
"killingSprees": 0,
"longestTimeSpentLiving": 422,
"totalDamageDealt": 143803,
"magicDamageDealt": 104935,
"physicalDamageDealt": 31981,
"trueDamageDealt": 6886,
},
{
"participantId": 6,
"teamId": 200,
"championId": 111,
"stats": {
"participantId": 6,
"win": false,
"kills": 1,
"deaths": 5,
"assists": 7,
"largestKillingSpree": 0,
"largestMultiKill": 1,
"longestTimeSpentLiving": 460,
"totalDamageDealt": 26611,
"magicDamageDealt": 9267,
"physicalDamageDealt": 11730,
"trueDamageDealt": 5613,
"largestCriticalStrike": 0,
},
{
"participantId": 7,
"teamId": 200,
"championId": 56,
"stats": {
"participantId": 7,
"win": false,
"kills": 3,
"deaths": 2,
"assists": 3,
"totalDamageDealt": 140699,
"magicDamageDealt": 5378,
"physicalDamageDealt": 131565,
"trueDamageDealt": 3755,
"largestCriticalStrike": 0,
"totalDamageDealtToChampions": 6557,
"magicDamageDealtToChampions": 455,
"physicalDamageDealtToChampions": 5549,
"trueDamageDealtToChampions": 552,
"totalHeal": 12548,
"totalUnitsHealed": 1,
"damageSelfMitigated": 13095,
"damageDealtToObjectives": 8279,
"damageDealtToTurrets": 791,
},
{
"participantId": 8,
"teamId": 200,
"championId": 55,
"stats": {
"participantId": 8,
"win": false,
"kills": 3,
"deaths": 5,
"assists": 1,
"largestKillingSpree": 2,
"largestMultiKill": 2,
"killingSprees": 1,
"longestTimeSpentLiving": 599,
"doubleKills": 1,
"tripleKills": 0,
"quadraKills": 0,
"pentaKills": 0,
"unrealKills": 0,
"totalDamageDealt": 98182,
"magicDamageDealt": 82014,
"physicalDamageDealt": 15485,
"trueDamageDealt": 682,
"largestCriticalStrike": 0,
"totalDamageDealtToChampions": 8542,
"magicDamageDealtToChampions": 6674,
"physicalDamageDealtToChampions": 1185,
"trueDamageDealtToChampions": 682,
},
{
"participantId": 9,
"teamId": 200,
"championId": 429,
"stats": {
"participantId": 9,
"win": false,
"kills": 4,
"deaths": 9,
"assists": 3,
"longestTimeSpentLiving": 489,
"totalDamageDealt": 83886,
"magicDamageDealt": 2860,
"physicalDamageDealt": 77851,
"trueDamageDealt": 3175,
"largestCriticalStrike": 290,
"totalDamageDealtToChampions": 16216,
"magicDamageDealtToChampions": 1500,
"physicalDamageDealtToChampions": 14715,
"trueDamageDealtToChampions": 0,
},
{
"participantId": 10,
"teamId": 200,
"championId": 68,
"stats": {
"participantId": 10,
"win": false,
"kills": 1,
"deaths": 4,
"assists": 0,
"totalDamageDealt": 88848,
"magicDamageDealt": 73156,
"physicalDamageDealt": 11816,
"trueDamageDealt": 3875,
"largestCriticalStrike": 0,
"totalDamageDealtToChampions": 12531,
"magicDamageDealtToChampions": 11890,
"physicalDamageDealtToChampions": 640,
"trueDamageDealtToChampions": 0,
},
}
],
}
如您所见,在显示比赛详细信息的 JSON 文件中,它显示了每个球员的统计数据。为了获取我的信息,我遍历了每个玩家,直到找到在那场比赛中扮演我的英雄的那个人,这显示在我过去比赛的 JSON 文件中。
因此,我所做的整个过程是:遍历每场比赛,保持“gameId”和“champion”的值,然后我用gameId搜索JSON文件,并循环遍历这个JSON的所有玩家,直到找到我的“冠军”,以便获取有关多少杀戮,死亡的信息......我在那场比赛中有多少。这是我的代码:
URL = "https://" + server + ".api.riotgames.com/lol/match/v4/matchlists/by-account/" + account_id + "?api_key=" + ApiKey
response = requests.get(URL)
old_games_json = response.json()
old_games_json = old_games_json['matches']
for index in range(len(old_games_json)):
champion = (old_games_json[index]['champion'])
gameid = (old_games_json[index]['gameId'])
URL = "https://" + server + ".api.riotgames.com/lol/match/v4/matches/" + str(gameid) + "?api_key=" + ApiKey
response = requests.get(URL)
game_json = response.json()
for player in range(len(game_json['participants'])):
if (game_json['participants'][player]['championId']) == champion:
win = game_json['participants'][player]['stats']["win"]
kills = game_json['participants'][player]['stats']["kills"]
deaths = game_json['participants'][player]['stats']["deaths"]
assists = game_json['participants'][player]['stats']["assists"]
问题是我在一个循环中循环,这需要大量时间来运行脚本。我的问题是,有什么方法可以让这个过程更快?
感谢您花时间阅读这篇文章。
解决方案
您可以使用 for-comprehension 构建字典champion_stats
,如下所示(以线性时间)。之后的主循环将只是线性时间(显示在底部)。请注意,数据已被简化。
old_games_json = {
"matches": [
{
"platformId": "EUW1",
"gameId": 4733037811,
"champion": 111,
},
{
"platformId": "EUW1",
"gameId": 4732867446,
"champion": 25
},
{
"platformId": "EUW1",
"gameId": 4731796980,
"champion": 53
}
]
}
game_json = {
"gameId": 4733037811,
"platformId": "EUW1",
"gameCreation": 1596031907965,
"gameDuration": 1624,
"queueId": 420,
"mapId": 11,
"seasonId": 13,
"gameVersion": "10.15.330.344",
"gameMode": "CLASSIC",
"gameType": "MATCHED_GAME",
"participants": [
{
"participantId": 1,
"teamId": 100,
"championId": 111,
"stats": {"win": 11}
},
{
"participantId": 2,
"teamId": 100,
"championId": 53,
"stats": {"win": 131}
},
{
"participantId": 3,
"teamId": 100,
"championId": 25,
"stats": {"win": 211}
}
]
}
champion_stats = dict((participant['championId'], participant['stats']) for participant in game_json['participants'])
for match in old_games_json['matches']:
champion_id = match['champion']
stats = champion_stats[champion_id]
# do stuff here with stats
print(stats)
输出
{'win': 11}
{'win': 211}
{'win': 131}
推荐阅读
- firebase - Firebase 自定义参数可以与 adwords 或任何谷歌广告一起使用吗?
- python - 使用 SCons 的 VariantDir 和 Repository 使用自定义生成器进行构建
- java - 如果它显示一个错误要求我检查此日志文件,我需要修复哪些错误才能启动我的 Eclipse?
- android - android ble connectGatt 超时
- java - 超过 1 小时后,Alarmmanager 不会触发服务 - 或者当应用程序处于打瞌睡状态时...... - Android Oreo
- macos-mojave - macos无法连接到L2TP服务器
- javascript - 如何编写将数组作为参数的javascript循环函数?
- arrays - 按值排序 [String: [String: Any]] 类型的字典
- assembly - 如何在另一个子程序中调用一个子程序?
- php - TYPO3 Hook 用于多种语言的预览