如何遍历嵌套字典(在嵌套列表中)并将值复制到新列表中
How can I iterate through a nested dictionary (withnin a nested list) and copy the values into a new list
我正在尝试对一组电子竞技游戏数据进行一些数据分析。数据格式如下(由json转换而来):
game_data = [{"match_id":1, "players":[{"player_name":"Tom", "won":True},
{"player_name":"Anna", "won":False}]},
{"match_id":2, "players":[{"player_name":"Tom", "won":False},
{"player_name":"Fred", "won":True}]}]
我想获取玩家“Tom”的列表,其中包含他的输赢。像这样:
tom_won = [True, False]
到目前为止我已经尝试过的方法(见下文)没有奏效,所以我希望你们中的一个人能够向我展示更好的方法。
index = 0
tom_won = []
while index < len(game_data)
for game_data[index]["players"][0]["won"] in data[index]:
if game_data[index]["players"][0]["player_name"] == "Tom":
tom_won.append(game_data[index]["players"][0]["won"])
for game_data[index]["players"][1]["won"] in data[index]:
if game_data[index]["players"][1]["player_name"] == "Tom":
tom_won.append(game_data[index]["players"][1]["won"])
index += 1
给你:
res = []
for game in game_data:
for player in game['players']:
if player['player_name'] == 'Tom':
res.append(player['won'])
print(res)
输出:
[True, False]
您需要遵循您的结构:
- 迭代外部数组中的匹配元素
- 对于每个数组,从键
'players'
给定的数组中迭代玩家
- 为每个玩家检查姓名,并检索
name
如果它是您正在寻找的玩家。
def get_won(data, name):
result = []
for match in data:
for player in match['players']:
if player['player_name'] == name:
result.append(player['won'])
return result
print(get_won(game_data, 'Tom')) # [True, False]
print(get_won(game_data, 'Fred')) # [True]
print(get_won(game_data, 'Anna')) # [False]
List-comprehension
版本
def get_won(data, name):
return [player['won'] for match in data for player in match['players']
if player['player_name'] == name]
这是一种通过列表理解来做到这一点的方法:
all_players = [p for m in game_data for p in m['players']]
tom = [m["won"] for m in all_players if m['player_name'] == "Tom"]
结果 [True, False]
试试这个:
game_data = [{"match_id":1, "players":[{"player_name":"Tom", "won":True},
{"player_name":"Anna", "won":False}]},
{"match_id":2, "players":[{"player_name":"Tom", "won":False},
{"player_name":"Fred", "won":True}]}]
tom_won = []
for each_match in game_data:
for each_player in each_match["players"]:
player_name = each_player["player_name"]
if player_name == "Tom":
tom_won.append(each_player["won"])
此外,您可以使用 defaultdict
:
获取所有玩家的成绩
game_data = [{"match_id":1, "players":[{"player_name":"Tom", "won":True},
{"player_name":"Anna", "won":False}]},
{"match_id":2, "players":[{"player_name":"Tom", "won":False},
{"player_name":"Fred", "won":True}]}]
import collections
player_won = collections.defaultdict(list)
for each_match in game_data:
for each_player in each_match["players"]:
player_name = each_player["player_name"]
player_won[player_name].append(each_player["won"])
我正在使用 python2.7,但代码应该很容易更改为 运行 in python3.
我建议先研究数据结构,例如:
game_data = [
{"match_id": 1, "results": {"Tom": True, "Anna": False}},
{"match_id": 2, "results": {"Tom": False, "Fred": True}}
]
然后您可以使用它来生成一位玩家的摘要:
>>> [match['results']['Tom'] for match in game_data]
[True, False]
这是 not a really good data structure,但至少更容易使用。
在 won
:
之间增加一点连贯性也是有意义的
game_data = [
{"match_id": 1, "winner": 1, "player_names": ["Anna", "Tom"]},
{"match_id": 2, "winner": 0, "player_names": ["Fred", "Tom"]},
]
然后:
def results(match, name):
return match['player_names'][match['winner']] == name
player_results = [results(match, 'Tom') for match in game_data]
为避免名称重复,您也可以使用玩家标识符:
from collections import namedtuple
Game = namedtuple('Game', ['match_id', 'winner', 'players'])
game_data = [
Game(match_id=1, winner=1, players=[0, 1]),
Game(match_id=2, winner=2, players=[1, 2]),
]
player_id = {name: i for i, name in enumerate(['Anna', 'Tom', 'Fred'])}
player_results = [game.winner == player_id['Tom'] for game in game_data]
您是唯一能够真正回答“什么是最好的数据结构”这个问题的人,但我希望这对您有所帮助。
另请注意,您可以简单地过滤结果以仅显示玩家参加的比赛,例如最后一个数据结构:
[game.winner == player_id['Fred'] for game in game_data if player_id['Fred'] in game.players]
这不是最简洁的形式,但您可以使用迭代器首先获取玩家参与的游戏,然后获取结果:
def player_games(games, name):
return (game for game in game_data if player_id[name] in game.players)
[game.winner == player_id['Fred'] for game in player_games(game_data, 'Fred')]
我正在尝试对一组电子竞技游戏数据进行一些数据分析。数据格式如下(由json转换而来):
game_data = [{"match_id":1, "players":[{"player_name":"Tom", "won":True},
{"player_name":"Anna", "won":False}]},
{"match_id":2, "players":[{"player_name":"Tom", "won":False},
{"player_name":"Fred", "won":True}]}]
我想获取玩家“Tom”的列表,其中包含他的输赢。像这样:
tom_won = [True, False]
到目前为止我已经尝试过的方法(见下文)没有奏效,所以我希望你们中的一个人能够向我展示更好的方法。
index = 0
tom_won = []
while index < len(game_data)
for game_data[index]["players"][0]["won"] in data[index]:
if game_data[index]["players"][0]["player_name"] == "Tom":
tom_won.append(game_data[index]["players"][0]["won"])
for game_data[index]["players"][1]["won"] in data[index]:
if game_data[index]["players"][1]["player_name"] == "Tom":
tom_won.append(game_data[index]["players"][1]["won"])
index += 1
给你:
res = []
for game in game_data:
for player in game['players']:
if player['player_name'] == 'Tom':
res.append(player['won'])
print(res)
输出:
[True, False]
您需要遵循您的结构:
- 迭代外部数组中的匹配元素
- 对于每个数组,从键
'players'
给定的数组中迭代玩家
- 为每个玩家检查姓名,并检索
name
如果它是您正在寻找的玩家。
def get_won(data, name):
result = []
for match in data:
for player in match['players']:
if player['player_name'] == name:
result.append(player['won'])
return result
print(get_won(game_data, 'Tom')) # [True, False]
print(get_won(game_data, 'Fred')) # [True]
print(get_won(game_data, 'Anna')) # [False]
List-comprehension
版本
def get_won(data, name):
return [player['won'] for match in data for player in match['players']
if player['player_name'] == name]
这是一种通过列表理解来做到这一点的方法:
all_players = [p for m in game_data for p in m['players']]
tom = [m["won"] for m in all_players if m['player_name'] == "Tom"]
结果 [True, False]
试试这个:
game_data = [{"match_id":1, "players":[{"player_name":"Tom", "won":True},
{"player_name":"Anna", "won":False}]},
{"match_id":2, "players":[{"player_name":"Tom", "won":False},
{"player_name":"Fred", "won":True}]}]
tom_won = []
for each_match in game_data:
for each_player in each_match["players"]:
player_name = each_player["player_name"]
if player_name == "Tom":
tom_won.append(each_player["won"])
此外,您可以使用 defaultdict
:
game_data = [{"match_id":1, "players":[{"player_name":"Tom", "won":True},
{"player_name":"Anna", "won":False}]},
{"match_id":2, "players":[{"player_name":"Tom", "won":False},
{"player_name":"Fred", "won":True}]}]
import collections
player_won = collections.defaultdict(list)
for each_match in game_data:
for each_player in each_match["players"]:
player_name = each_player["player_name"]
player_won[player_name].append(each_player["won"])
我正在使用 python2.7,但代码应该很容易更改为 运行 in python3.
我建议先研究数据结构,例如:
game_data = [
{"match_id": 1, "results": {"Tom": True, "Anna": False}},
{"match_id": 2, "results": {"Tom": False, "Fred": True}}
]
然后您可以使用它来生成一位玩家的摘要:
>>> [match['results']['Tom'] for match in game_data]
[True, False]
这是 not a really good data structure,但至少更容易使用。
在 won
:
game_data = [
{"match_id": 1, "winner": 1, "player_names": ["Anna", "Tom"]},
{"match_id": 2, "winner": 0, "player_names": ["Fred", "Tom"]},
]
然后:
def results(match, name):
return match['player_names'][match['winner']] == name
player_results = [results(match, 'Tom') for match in game_data]
为避免名称重复,您也可以使用玩家标识符:
from collections import namedtuple
Game = namedtuple('Game', ['match_id', 'winner', 'players'])
game_data = [
Game(match_id=1, winner=1, players=[0, 1]),
Game(match_id=2, winner=2, players=[1, 2]),
]
player_id = {name: i for i, name in enumerate(['Anna', 'Tom', 'Fred'])}
player_results = [game.winner == player_id['Tom'] for game in game_data]
您是唯一能够真正回答“什么是最好的数据结构”这个问题的人,但我希望这对您有所帮助。
另请注意,您可以简单地过滤结果以仅显示玩家参加的比赛,例如最后一个数据结构:
[game.winner == player_id['Fred'] for game in game_data if player_id['Fred'] in game.players]
这不是最简洁的形式,但您可以使用迭代器首先获取玩家参与的游戏,然后获取结果:
def player_games(games, name):
return (game for game in game_data if player_id[name] in game.players)
[game.winner == player_id['Fred'] for game in player_games(game_data, 'Fred')]