是否可以将此代码转换为使用生成器而不是列表?

2024-05-18 15:32:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这样一个结构(伪代码):

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()的三个调用来保存:

  1. 每个玩家的数据在一个executemany()
  2. 每个英雄的数据在一个executemany()
  3. 一个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。你知道吗

编辑:另外,我不想在玩家之间循环三次。所以我想在一个循环中得到三台发电机。你知道吗


Tags: 数据iddatasaveleveldatabaseskillsclass
1条回答
网友
1楼 · 发布于 2024-05-18 15:32:05

如果您想在数据库上以单独的操作保存玩家、英雄和技能数据集(而不是用每个玩家的相关英雄和技能数据为每个玩家执行一个操作,或者以某种方式并行保存),则无法避免存储O(len(players))值的数据。你知道吗

发电机在这里帮不了你。即使您可以使用一个返回英雄和技能数据的生成器,它也需要在后台维护一个列表(或其他一些数据结构),除非您的三个数据库同时保存。您可能希望将您所请求的内容与the implementation of ^{}进行比较,后者将创建输入迭代器的几个“副本”。只有在并行迭代副本(例如,zip)而不是逐个迭代副本时,它才是节省空间的。如果你一个接一个地迭代这些副本,这与将迭代器的内容复制到一个列表中并反复迭代是一样的。你知道吗

相关问题 更多 >

    热门问题