当我在调查Javascript代码中的词法闭包问题时,我在Python中遇到了这个问题:
flist = []
for i in xrange(3):
def func(x): return x * i
flist.append(func)
for f in flist:
print f(2)
Run Code Online (Sandbox Code Playgroud)
请注意,此示例谨慎避免lambda.它打印"4 4 4",这是令人惊讶的.我期待"0 2 4".
这个等效的Perl代码是正确的:
my @flist = ();
foreach my $i (0 .. 2)
{
push(@flist, sub {$i * $_[0]});
}
foreach my $f (@flist)
{
print $f->(2), "\n";
}
Run Code Online (Sandbox Code Playgroud)
打印"0 2 4".
你能解释一下这个区别吗?
更新:
这个问题是不是与i是全球性的.这显示相同的行为:
flist = []
def outer():
for i in xrange(3):
def inner(x): return x * i …Run Code Online (Sandbox Code Playgroud) 我正在尝试在循环内创建函数并将它们存储在字典中.问题是字典中的所有条目似乎最终都映射到最后创建的函数.代码如下:
functions = []
for i in range(3):
def f():
return i
# alternatively: f = lambda: i
functions.append(f)
Run Code Online (Sandbox Code Playgroud)
这输出:
print([f() for f in functions])
# expected output: [0, 1, 2]
# actual output: [2, 2, 2]
Run Code Online (Sandbox Code Playgroud)
知道为什么吗?
如果我制作两个函数列表:
def makeFun(i):
return lambda: i
a = [makeFun(i) for i in range(10)]
b = [lambda: i for i in range(10)]
Run Code Online (Sandbox Code Playgroud)
为什么名单a和b不相等?
例如:
>>> a[2]()
2
>>> b[2]()
9
Run Code Online (Sandbox Code Playgroud) 我试图在循环中创建lambdas迭代一个对象列表:
lambdas_list = []
for obj in obj_list:
lambdas_list.append(lambda : obj.some_var)
Run Code Online (Sandbox Code Playgroud)
现在,如果我遍历lambdas列表并像这样调用它们:
for f in lambdas_list:
print f()
Run Code Online (Sandbox Code Playgroud)
我得到了相同的价值.这是最后的价值obj在obj_list,因为那是在列表迭代器的块中的最后一个变量.任何想法都能很好地(pythonic)重写代码以使其工作?
是否有任何python大师能够解释为什么这段代码不起作用:
def f(code_str):
exec(code_str)
code = """
g = 5
x = [g for i in range(5)]
"""
f(code)
Run Code Online (Sandbox Code Playgroud)
错误:
Traceback (most recent call last):
File "py_exec_test.py", line 9, in <module>
f(code)
File "py_exec_test.py", line 2, in f
exec(code_str)
File "<string>", line 3, in <module>
File "<string>", line 3, in <listcomp>
NameError: name 'g' is not defined
Run Code Online (Sandbox Code Playgroud)
虽然这个工作正常:
code = """
g = 5
x = [g for i in range(5)]
"""
exec(code)
Run Code Online (Sandbox Code Playgroud)
我知道它与locals和globals有关,就好像我从我的主范围传递exec函数locals和globals它工作正常,但我不完全理解发生了什么.
这可能是Cython的一个错误吗?
编辑:尝试使用python 3.4.0和python 3.4.3
先读这个。它是关于lambda x=x: foo(x)即使在for循环中也能捕获 x 。
这是一个带有标签和for循环生成的两个按钮的窗口。单击按钮时,它的名称出现在标签中。
如果我们使用 normal lambda: label.setText("button -- " + str(i)),那么结果是 lasti无论按下什么按钮,循环中的:

这是正确的。
当我们改为 lambda i=i: label.setText("button -- " + str(i))(snipet) 并期望现在一切正常时,结果是:
![拉姆达 i=i:foo(i)]](https://i.stack.imgur.com/vbbPq.jpg)
错误的!
这False是从哪里来的?
import sys
from PyQt4.QtGui import *
class MainWindow(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
vbox = QVBoxLayout(self)
# label for action
label = QLabel('')
vbox.addWidget(label)
# adding buttons
for i in range (1, 3):
btn = QPushButton(str(i))
btn.clicked.connect( lambda i=i: label.setText("button …Run Code Online (Sandbox Code Playgroud) 我正在尝试从QtGui.QPushButton对象列表创建一个简单的键盘。
class XKeyboard(QtGui.QWidget):
'''Special virtual keyboard for any language.'''
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.MainLayout = QtGui.QVBoxLayout()
self.TextEntry = QtGui.QTextEdit()
self.Keyboard = QtGui.QVBoxLayout()
self.MainLayout.addWidget(self.TextEntry)
self.MainLayout.addLayout(self.Keyboard)
self.setLayout(self.MainLayout)
def addRow(self, keys):
layout = QtGui.QHBoxLayout()
buttons = [QtGui.QPushButton(unicode(key)) for key in keys]
for button in buttons:
key = keys[buttons.index(button)]
layout.addWidget(button)
button.clicked.connect(
lambda key: self.keyClick(key))
self.keyClick(key)
self.Keyboard.addLayout(layout)
def keyClick(self, key):
self.TextEntry.insertPlainText(key)
Run Code Online (Sandbox Code Playgroud)
问题是lambda返回False而不是键。我究竟做错了什么?
我正在尝试制作一个程序来创建格式的 lambda 函数列表y=mx+b,其中“m”和“b”是预先确定的值
我的总体目标是实现一个功能,那
基本上,如果你知道那是什么,像霍夫变换的东西。
一旦我有了特定图像的线条,我就可以创建一个 lambda 函数来表示线条的斜率及其起点。我遇到了无法将 lambda 函数附加到列表的问题。
我试过这个:
if __name__ == "__main__":
nums = []
for i in range(10):
j = lambda x: x + i
nums.append(j)
for i in nums:
print(i(1))
Run Code Online (Sandbox Code Playgroud)
这是我得到的错误:
Traceback (most recent call last):
File "C:/Users/me/.PyCharmCE2018.3/config/scratches/scratch_3.py", line 7, in <module>
print(i(1))
File "C:/Users/me/.PyCharmCE2018.3/config/scratches/scratch_3.py", line 4, in <lambda>
j = (lambda x: x + i)
TypeError: unsupported operand type(s) for +: 'int' and 'function'
Run Code Online (Sandbox Code Playgroud) python ×8
lambda ×3
pyqt ×2
append ×1
closures ×1
function ×1
late-binding ×1
pyqt4 ×1
python-exec ×1
qt ×1
qt-signals ×1
scope ×1