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

Python 是否可以将此代码转换为使用生成器而不是列表?,python,python-3.x,generator,Python,Python 3.x,Generator,我有这样一个结构(伪代码): 现在我试图将其存储到数据库中,我给了我的播放器一个get\u serialized\u data()方法,该方法返回一个元组,如下所示: return ( # players (steamid, hero.class_id), # heroes (steamid, hero.class_id, hero.level, hero.xp), # skills ( (steamid, hero.class_i

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

现在我试图将其存储到数据库中,我给了我的播放器一个
get\u serialized\u 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()
    
    正如你所看到的,“问题”是我构造了三个大列表。是否有可能以某种方式将这些列表替换为生成器?我的
    \u database.save\u X()
    方法都接受生成器,因此它将节省大量RAM


    编辑:另外,我不想在玩家之间循环三次。因此,我希望在一个循环中以某种方式获得三个生成器。

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


    生成器在这里对您没有帮助。即使您可以找到一个返回英雄和技能数据的生成器,它也需要在后台维护一个列表(或其他一些数据结构),除非您的三次数据库保存是并行进行的。您可能希望比较您要求的内容,这会创建多个“副本”一个输入迭代器。只有在并行迭代副本时(例如,
    zip
    ),而不是一个一个地迭代副本时,才具有空间效率。如果一个一个地迭代副本,本质上与将迭代器的内容复制到列表中并重复迭代相同。

    “三个大列表”–我们实际上谈论的是多大?
    player\u data
    hero\u data
    似乎分别是2元组和4元组。如果您使用的是Python 3,那么
    skills\u data
    应该已经是4元组的生成器(因为您使用的是生成器表达式
    (用于hero.skills中的技能)
    )玩家的数量可以是1到5000,英雄的数量总是等于玩家的数量,每个英雄可以有4到15种技能。我说的是
    players\u data
    heros\u data
    ,和
    skills\u data
    列表,希望把它们变成
    的生成器(元组,元组,生成器[tuple])
    而不是
    (tuple,tuple,generator[tuple])
    的列表。这是相关的,因为一个包含15项的列表什么都不是(你从那里的生成器那里什么也得不到)甚至5000也不是那么多。你还必须考虑数据是从哪里来的。数据已经在内存中了吗?还是你懒洋洋地从其他地方读到它?返回一个没有太多数据的三元组,所以这没有多大意义,所以我觉得您想要打开
    \u players.values()
    到生成器中,但你根本不显示玩家是什么。所以我不知道我们应该如何帮助你。5000名玩家没有那么多,但请记住,英雄的数量是相等的,每个英雄都有4-15项技能。这大约是100000项。数据已经存在,所以它已经存在于RAM中,但我还是不喜欢o尽可能避免列表。正如我所说,我想将当前的
    玩家数据
    英雄数据
    技能数据
    转化为生成器。它们当前是列表。
    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()