映射函数或 lambda 在 Python 中无法按预期工作

Posted

技术标签:

【中文标题】映射函数或 lambda 在 Python 中无法按预期工作【英文标题】:Map function or lambda does not work as expected in Python 【发布时间】:2022-01-13 00:22:15 【问题描述】:

我的代码没有按预期工作。我的部分代码如下所示:

lst_of_players = []

class Player:
    def __init__(self, username):
        self.username = username
        self.level = 1
        lst_of_players.append(self)

    def level_up(self):
        self.level += 1


player1 = Player("Player 1")
player2 = Player("Player 2")
player3 = Player("Player 3")

def level_up_all_players():
    map(lambda player: player.level_up(), lst_of_players)

当我调用 level_up_all_players 函数时,我以为玩家的等级会提升 1,但事实并非如此。 当我打印玩家的等级时,他们仍然是调用函数之前的等级。

【问题讨论】:

您还应该将每个玩家添加到您的lst_of_players;就目前而言,您的最小示例将不起作用,因为列表中没有任何内容。我认为这是需要调用地图的一个附带问题(因为它是延迟加载的)。 【参考方案1】:

map() 过去在 Python 2.7 中可以正常工作,但现在 map() 在 Python 3.x 中是惰性的,所以你必须强制它工作。将level_up_all_players() 的最后一行放在list() 中,如下所示:

list(map(lambda player: player.level_up(), lst_of_players))

但是,不建议这样做。仅将 map() 用于副作用通常不是一个好习惯(在您的情况下,代码只是将 1 添加到玩家的级别)。 通常,您使用map() 生成的结果。

所以,我真的认为你应该使用for 循环来完成这种工作,而且对于我和其他许多人来说,它比maplambda 更容易阅读:

for player in lst_of_players:
    player.level_up()

更新

如果你真的想用一行代码实现同样的效果,你可以这样做:

for player in lst_of_players: player.level_up()

我在 Python 中发现了一个类似的关于 map() 的 SO 帖子。请看一下:link to the post

【讨论】:

【参考方案2】:

map 是惰性的:在您实际迭代 map 对象之前,不会应用该函数。

不过,map 和列表推导式都不应该仅用于对值调用的函数的副作用。仅当您想要每个函数调用的返回值时才使用它。只需使用常规的 for 循环即可:

for p in lst_of_players:
    p.level_up()

【讨论】:

以上是关于映射函数或 lambda 在 Python 中无法按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

如何在python中映射具有多个参数的函数

map()函数 lambda函数 zip()函数的使用

Python 函数随笔 map()函数,lambda自定义函数

AWS Lambda Python3.7 函数 - numpy:无法导入名称“WinDLL”

在 Python 中映射 if 语句

Python匿名函数/排序函数/过滤函数/映射函数/递归/二分法