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()