相关疑难解决方法(0)

(lambda)函数闭包捕获了什么?

最近我开始玩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从中循环03.对于这些数字中的每一个,lambda都会创建一个函数i,该函数捕获并将其添加到函数的输入中.最后一行将第二个lambda函数3作为参数调用.令我惊讶的是输出结果是6.

我期待一个4.我的理由是:在Python中,一切都是一个对象,因此每个变量都是指向它的指针.在创建lambda闭包时i,我希望它存储一个指向当前指向的整数对象的指针i.这意味着当i分配一个新的整数对象时,它不应该影响先前创建的闭包.遗憾的是,adders在调试器中检查数组表明它确实存在.所有的lambda功能指的最后一个值i,3,这将导致adders[1](3)返回6.

这让我想知道以下内容:

  • 闭包捕获的内容是什么?
  • 什么是最优雅的方式来说服lambda函数以更改其值i时不会受到影响的方式捕获当前i值?

python lambda closures

237
推荐指数
5
解决办法
4万
查看次数

在循环中创建函数

我正在尝试在循环内创建函数并将它们存储在字典中.问题是字典中的所有条目似乎最终都映射到最后创建的函数.代码如下:

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)

知道为什么吗?

python function

79
推荐指数
2
解决办法
3万
查看次数

地图与列表; 为何不同的行为?

在为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)

python functional-programming python-3.x

13
推荐指数
2
解决办法
476
查看次数

检查按钮和按钮:使用lambda

我试图根据列表创建一些复选框,但看起来好像我搞砸了命令调用和按钮的可变方面.

我的代码是:

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".

python user-interface tkinter

3
推荐指数
1
解决办法
703
查看次数

Python tkinter查找单击了哪个按钮

我正在尝试实现一个名为“五连胜”的游戏。我创建了一个 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 中的按钮网格?. 但我不太明白。

python tkinter

3
推荐指数
1
解决办法
6590
查看次数

在python 3中应用python 2代码的麻烦

要了解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)

python lambda filter

1
推荐指数
1
解决办法
90
查看次数

PyQt/Pyside - 动态创建和连接 - 捕获 lambda 中的函数和参数

我正在尝试重新创建 Windows 记事本。

\n\n

我目前正在搞乱QMenuBar

\n\n

我制作了一本字典,其中包含以下模式的所有菜单和操作:

\n\n
menus = {'File':[['New', 'Ctrl+n'],\n                 ['Open', 'Ctrl+o'],\n                 ['Save', 'Ctrl+s'],\n                 ['Save as...', None],\n                 'Separator', \n                 # and so on\n
Run 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\n

我这样做是这样的:

\n\n
for 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))\n
Run Code Online (Sandbox Code Playgroud)\n\n

它连接成功,但如果我尝试使用任何操作,它不会执行任何操作。

\n\n

我以前曾使用 lambda 函数连接操作,但这是我第一次使用 …

python lambda pyqt pyside getattr

0
推荐指数
1
解决办法
1538
查看次数