我很懂函数式编程。我想要创建一个函数列表,每个函数都选择一个列表的不同元素。我把我的问题简化为一个简单的例子。当然,这是一个Python错误:
fun_list = []
for i in range(5):
def fun(e):
return e[i]
fun_list.append(fun)
mylist = range(10)
print([f(mylist) for f in fun_list])“显然”它应该返回0,1,2,3, 4,但是它返回4,4,4,4,4,4,4。我怎么能强迫Python去做正确的事情呢?(这一点以前没有被注意到吗?还是我只是太笨了?)
这是Python3.4.0(默认,2014年3月25日,11:07:05)
谢谢你,大卫
发布于 2014-04-16 05:14:22
我怎样才能强迫Python做正确的事情呢?
以下是一种方法:
fun_list = []
for i in range(5):
def fun(e, _ndx=i):
return e[_ndx]
fun_list.append(fun)
mylist = range(10)
print([f(mylist) for f in fun_list])这是因为在执行_ndx的def语句时会计算和保存fun的默认值。(在python中,执行def语句。)
发布于 2014-04-16 05:15:42
这肯定是个Python虫..。
这是对范围的误解。由于fun()的所有五个实例都定义在相同的作用域中,因此它们都具有该作用域中所有名称的相同值,包括i。为了解决这个问题,您需要将使用的值与包含循环本身的作用域分开。这可以通过在完全不同的范围内定义函数来实现。
fun_list = []
def retfun(i):
def fun(e):
return e[i]
return fun
for i in range(5):
fun_list.append(retfun(i))
mylist = range(10)
print([f(mylist) for f in fun_list])发布于 2014-04-16 05:11:28
您可以使用itemgetter来完成这个任务。
from operator import itemgetter
fun_list = []
for i in range(5):
fun_list.append(itemgetter(i))
mylist = range(10)
print([f(mylist) for f in fun_list])在您的示例中,您将一个函数分配给所有引用全局i的元素,调用时的值为i,所有调用的值为4。你需要某种竞逐。
没有itemgetter也一样
def indexer(i): return lambda y: y[i]
fun_list = []
for i in range(5):
fun_list.append(indexer(i))
mylist = range(10)
print([f(mylist) for f in fun_list])https://stackoverflow.com/questions/23100401
复制相似问题