深层嵌套字典/地图情况所需的替代数据结构

时间:2012-06-01 21:56:52

标签: python data-structures

数据的某些背景:正在播放一些不同的游戏,每个游戏都会托管多个玩家。每场比赛由多轮组成,每轮比赛中,每位参与者都会采取行动。我在这里要做的是在内存中构建一个数据结构,用于存储玩家在所有正在玩的游戏中所采取的各个动作的完整历史记录。

明显的结构是深度嵌套的字典/散列映射,其中每个game_id都映射到多个player_id,每个player_id映射到不同的round_number 1}} s,每个round_number都映射到action

换句话说,game_id:player_id:round_number:action。另一方面,我也可以使用game_id:round_number:player_id:action

当我尝试访问上面的数据结构以用于不同的分析目的时,

出现问题。例如,如果我想知道玩家在给定游戏的特定轮次中所做的所有动作,那么拥有game_id:player_id:round_number:action是不方便的。相反,如果我想知道特定玩家在给定游戏过程中所做的所有动作,那么game_id:round_number:player_id:action同样不方便。不幸的是,就我而言,我需要经常问这两个问题。

我想知道是否存在单个数据结构,它可以存储这样的数据,并且便于访问如上所述的播放器级和圆级数据。如果重要的话,实现将在Python中。

编辑:有些人推荐使用内存中的sqlite数据库来处理此类关系查询。但是,它的性能可能对我来说是个问题,如下所述:SQLite Performance Benchmark -- why is :memory: so slow...only 1.5X as fast as disk?

3 个答案:

答案 0 :(得分:3)

一种方法是将数据存储在dict中,但保留索引以允许快速访问数据中的各种视图。您可以使用类或函数来构造它。以下是jist(未经测试):

from collections import defaultdict

game_dict = {}  # keyed by (game, player, round) tuple
game_player_ix = defaultdict(list)
game_round_ix = defaultdict(list)

def add_action(game, player, round):
    game_dict[(game, round, player)] = action # track the action in the main dict
    game_player_ix[(game, player)].append(round)  # keep an index for lookups by player
    game_round_ix[(game, round)].append(player) # another index for lookups by round

def get_all_player_actions(game, player):
    return (game_dict[(game,player,round)] for round in game_round_ix[(game, player)]) # iterator

def get_all_round_actions(game, round):
    return (game_dict[(game,player,round)] for player in game_player_ix[(game, round)]) # iterator

答案 1 :(得分:1)

我建议

  1. 编写一个具有将公共访问模式包装到嵌套映射的函数的类。
  2. 使用sqlite3 database
  3. 编辑:

    我误解了这个问题,抱歉。

    我想不出一个可以做到这一点的单一数据结构,尽管稍微复制数据也不会太糟糕。让玩家成为一个类,你可以让玩家将玩家地图存储到动作中,并让玩家类包含该玩家所采取的动作列表。

答案 2 :(得分:0)

你可以存储一组元组,其中每个元组只存储普通(game_id,player_id,round_number,action)。您也可以使用播放器名称的interned strings而不是ID。如果您不知道要做什么分析,那么这种格式可以使每个字段均等地进行统计分析,如果您认为将来需要,可以很容易地转换为数据库中的存储。

也可能使用named tuple