提问人:Plaikeeaan 提问时间:8/7/2022 更新时间:8/7/2022 访问量:128
在 for 循环中创建的 lambda 函数的 Python 列表在具有不同 id [duplicate] 时行为相同
Python list of lambda functions created in a for loop behave the same while having a different id [duplicate]
问:
我正在尝试解决经典的 FizzBuzz 问题
- 打印从 1 到 N 的所有数字
- 但是,如果能被 3 整除,则提示“嘶嘶声”
- 但是,如果能被 5 整除,则提示“Buzz”
- 但是,如果能被 3 和 5 整除,则提示“FizzBuzz”
- 但是,如果能被 m 整除,那么等等......
在 Python 中以很多奇特的方式。其中之一是从字典中创建一个函数列表,以应用于 N 个数字。但是我遇到了一个意想不到的行为。我在 for 循环中创建了一个包含 3 个 lambda 函数的列表。它们的 id 不同,但它们都表现为最后创建的函数。我知道处理列表中的可变对象可能很棘手,但我无法理解这种行为。最好的方法是向你展示代码:
data = {3: "Fizz",
5: "Buzz",
7: "Bazz",}
def closures_on_dict(dictionnaire):
"""Create a list of functions x->f(x) from a dictionary
The int key being a divisor, the string value being the prompted value
if x is divisible by the divisor"""
functions = list()
ii = 0
for divisor, sentance in dictionnaire.items():
print(f"divisor id: {(divisor)}, sentance id: {id(sentance)}")
functions += [lambda x: sentance if x%divisor == 0 else x]
print(f"function id: {id(functions[ii])}")
ii +=1
return functions
###############################################################################
if __name__=="__main__":
functions = closures_on_dict(data)
for ii, function in enumerate(functions):
print(f"function[{ii}] id is: {id(function)}")
for test in data.keys():
print(f"\t function[{ii}]({test}) = {function(test)}")
结果是......
divisor id: 3, sentance id: 140444073732784
function id: 140444096066176
divisor id: 5, sentance id: 140444073732016
function id: 140444096066752
divisor id: 7, sentance id: 140444072258672
function id: 140444096065600
function[0] id is: 140444096066176
function[0](3) = 3
function[0](5) = 5
function[0](7) = Bazz
function[1] id is: 140444096066752
function[1](3) = 3
function[1](5) = 5
function[1](7) = Bazz
function[2] id is: 140444096065600
function[2](3) = 3
function[2](5) = 5
function[2](7) = Bazz
所以他们的 ID 不同,但它们的工作方式都一样。显然有一个简单的解决方法:
def dirty_patch(key, value):
return lambda x: value if x%key == 0 else x
然后它完美地工作:
function[0] id is: 140444096048576
function[0](3) = Fizz
function[0](5) = 5
function[0](7) = 7
function[1] id is: 140444096049008
function[1](3) = 3
function[1](5) = Buzz
function[1](7) = 7
function[2] id is: 140444096217440
function[2](3) = 3
function[2](5) = 5
function[2](7) = Bazz
但是我想知道为什么当我在 closures_on_dict() 中创建 lambda 函数时,即使具有不同的 id,它们的行为也相同?我认为它与 for 循环中的可变参数“除数”和“句子”有关,但我在 Python 方面不够熟练,无法理解问题出在哪里。
答: 暂无答案
评论
def foo(): print(x)
x = 2; foo()
x =22; foo()
x
x