我有这样一个结构(伪代码):
class Player {
steamid: str
hero: Hero
}
class Hero {
class_id: str
level: int
xp: int
skills: list[Skill]
}
class Skill {
class_id: str
level: int
}
现在我尝试将它存储到数据库中,我给了我的播放器一个get_serialized_data()
方法,它返回一个元组,如下所示:
return (
# players
(steamid, hero.class_id),
# heroes
(steamid, hero.class_id, hero.level, hero.xp),
# skills
(
(steamid, hero.class_id, skill.class_id, skill.level)
for skill in hero.skills
),
)
最后,我同时将每个玩家的数据存储到数据库中,并使用对executemany()
的三个调用来保存:
executemany()
executemany()
executemany()
中每个技能的数据下面是我的代码:
def save_all_data(*, commit=True):
"""Save every active player's data into the database."""
players_data = []
heroes_data = []
skills_data = []
for player in _players.values():
player_data, hero_data, skills_data_ = player.get_serialized_data()
players_data.append(player_data)
heroes_data.append(heroes_data)
skills_data.extend(skills_data_)
_database.save_players(players_data)
_database.save_heroes(heroes_data)
_database.save_skills(skills_data)
if commit:
_database.commit()
如你所见,问题是我构造了三个大列表。有没有可能用生成器替换这些列表?我的_database.save_X()
方法都接受生成器,因此可以节省大量的RAM。你知道吗
编辑:另外,我不想在玩家之间循环三次。所以我想在一个循环中得到三台发电机。你知道吗
如果您想在数据库上以单独的操作保存玩家、英雄和技能数据集(而不是用每个玩家的相关英雄和技能数据为每个玩家执行一个操作,或者以某种方式并行保存),则无法避免存储
O(len(players))
值的数据。你知道吗发电机在这里帮不了你。即使您可以使用一个返回英雄和技能数据的生成器,它也需要在后台维护一个列表(或其他一些数据结构),除非您的三个数据库同时保存。您可能希望将您所请求的内容与the implementation of ^{} 进行比较,后者将创建输入迭代器的几个“副本”。只有在并行迭代副本(例如,
zip
)而不是逐个迭代副本时,它才是节省空间的。如果你一个接一个地迭代这些副本,这与将迭代器的内容复制到一个列表中并反复迭代是一样的。你知道吗相关问题 更多 >
编程相关推荐