最近我开始玩Python,我遇到了一些特殊的闭包方式.请考虑以下代码:
adders=[0,1,2,3]
for i in [0,1,2,3]:
adders[i]=lambda a: i+a
print adders[1](3)
Run Code Online (Sandbox Code Playgroud)
它构建了一个简单的函数数组,它接受单个输入并返回由数字添加的输入.函数在for循环中构造,迭代器i从中循环0到3.对于这些数字中的每一个,lambda都会创建一个函数i,该函数捕获并将其添加到函数的输入中.最后一行将第二个lambda函数3作为参数调用.令我惊讶的是输出结果是6.
我期待一个4.我的理由是:在Python中,一切都是一个对象,因此每个变量都是指向它的指针.在创建lambda闭包时i,我希望它存储一个指向当前指向的整数对象的指针i.这意味着当i分配一个新的整数对象时,它不应该影响先前创建的闭包.遗憾的是,adders在调试器中检查数组表明它确实存在.所有的lambda功能指的最后一个值i,3,这将导致adders[1](3)返回6.
这让我想知道以下内容:
lambda函数以更改其值i时不会受到影响的方式捕获当前i值?我正在尝试在循环内创建函数并将它们存储在字典中.问题是字典中的所有条目似乎最终都映射到最后创建的函数.代码如下:
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)
知道为什么吗?
在为Bayes'Nets程序实现"变量消除"算法的过程中,我遇到了一个意外的错误,这是一系列对象的迭代映射转换的结果.
为简单起见,我将在这里使用类似的代码:
>>> nums = [1, 2, 3]
>>> for x in [4, 5, 6]:
... # Uses n if x is odd, uses (n + 10) if x is even
... nums = map(
... lambda n: n if x % 2 else n + 10,
... nums)
...
>>> list(nums)
[31, 32, 33]
Run Code Online (Sandbox Code Playgroud)
这绝对是错误的结果.由于[4,5,6]包含两个偶数,10因此每个元素最多应加两次.我在VE算法中也遇到了意想不到的行为,因此我修改它以在每次迭代后将迭代map器转换为a list.
>>> nums = [1, 2, 3]
>>> for x in [4, 5, 6]:
... # Uses n if …Run Code Online (Sandbox Code Playgroud) 我试图根据列表创建一些复选框,但看起来好像我搞砸了命令调用和按钮的可变方面.
我的代码是:
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.initUI()
def initUI(self):
self.courses = ["CSE 4444", "CSE 4343"]
self.vars = []
self.parent.title("Homework Helper")
self.course_buttons()
self.pack(fill=BOTH, expand=1)
def course_buttons(self):
x = 0
y = 0
for i in range(0, len(self.courses)):
self.vars.append(IntVar())
cb = Checkbutton(self, text=self.courses[i],
variable=self.vars[i],
command=lambda: self.onClick(i))
cb.select()
cb.grid(column=x, row=y)
y = y+1
def onClick(self, place):
print place
if self.vars[place].get() == 1:
print self.courses[place]
Run Code Online (Sandbox Code Playgroud)
到目前为止的测试是在复选框打开时在控制台上打印课程,但它仅适用于第二个按钮"CSE 4343"按钮.当我与按钮"CSE 4444"交互时,没有打印任何内容.
此外,"place"值onClick始终为1,无论我是单击按钮"CSE 4343"还是按钮"CSE 4444".
我正在尝试实现一个名为“五连胜”的游戏。我创建了一个 15×15 的列表来放置按钮。(我使用 range(16) 因为我还想要一行和一列来显示行号和列号)
我希望我的实现就像一个按钮被点击时一样,它变成了一个标签。但我不知道用户点击了哪个按钮。
我怎样才能实现它?谢谢!
from tkinter import *
root=Tk()
root.wm_title("Five In a Row")
buttonlst=[ list(range(16)) for i in range(16)]
chess=Label(root,width=2,height=2,text='0')
def p(button):
gi=button.grid_info()
x=gi['row']
y=gi['column']
button.grid_forget()
chess.grid(row=x,column=y)
buttonlst[x][y]=chess
for i in range(16):
for j in range(16):
if i==0:
obj=Label(root,width=2,text=hex(j)[-1].upper())
elif j==0:
obj=Label(root,width=2,text=hex(i)[-1].upper())
else:
obj=Button(root,relief=FLAT,width=2,command=p(obj))
obj.grid(row=i,column=j)
buttonlst[i][j]=obj
root.mainloop()
Run Code Online (Sandbox Code Playgroud)
有一个类似的问题如何确定哪个按钮被按下了 Python TKinter 中的按钮网格?. 但我不太明白。
要了解lambdas,我正在学习本教程,并遇到了关于计算素数的例子(python 2.x):
nums = range(2,50)
for i in range(2,8):
nums = filter(lambda x: x == i or x % i, nums)
print (list(nums))
Run Code Online (Sandbox Code Playgroud)
版画
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
Run Code Online (Sandbox Code Playgroud)
但是,在python 3.4中尝试这个时,它产生了意想不到的行为:
nums = range(2,50)
for i in range(2,8):
nums = filter(lambda x: x == i or x % i , nums)
print(list(nums))
Run Code Online (Sandbox Code Playgroud)
版画
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, …Run Code Online (Sandbox Code Playgroud) 我正在尝试重新创建 Windows 记事本。
\n\n我目前正在搞乱QMenuBar
我制作了一本字典,其中包含以下模式的所有菜单和操作:
\n\nmenus = {'File':[['New', 'Ctrl+n'],\n ['Open', 'Ctrl+o'],\n ['Save', 'Ctrl+s'],\n ['Save as...', None],\n 'Separator', \n # and so on\nRun Code Online (Sandbox Code Playgroud)\n\n然后我迭代该字典,并成功创建菜单和操作并将它们存储在第二个字典中。
\n\n现在我正在尝试连接每个action[new, open, save, \xe2\x80\xa6] to a instance method of the same name.
我这样做是这样的:
\n\nfor action in menus[m]:\n action = menu.addAction(action[0])\n\n if action[1]:\n action.setShortcut(QKeySequence(action[1]))\n\n if isinstance(action, QAction):\n fname = action[0].lower() \n # and some other string manipulations\n func = getattr(self,fname)\n action.triggered.connect(lambda arg=action: func(arg))\nRun Code Online (Sandbox Code Playgroud)\n\n它连接成功,但如果我尝试使用任何操作,它不会执行任何操作。
\n\n我以前曾使用 lambda 函数连接操作,但这是我第一次使用 …