在实施"变量消除"贝叶斯的算法'网络程序,我遇到了一个意外的错误,这是一系列对象的迭代映射转换的结果。
为简单起见,我在这里使用类似的代码:
>>> 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]
这绝对是错误的结果。由于[4,5,6]包含两个偶数,因此应将10
添加到每个元素最多两次。我在VE算法中也遇到了意想不到的行为,所以我修改它以在每次迭代后将map
迭代器转换为list
。
>>> 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)
... nums = list(nums)
...
>>> list(nums)
[21, 22, 23]
根据我对可迭代的理解,这个修改不应该改变任何东西,但确实如此。显然,n + 10
案例的not x % 2
转换在list
版本中应用次数较少。
My Bayes Nets程序在发现此错误后也能正常工作,但我正在寻找解释原因的原因。
答案 0 :(得分:12)
答案非常简单:{3}}是Python 3中的map
函数,它返回一个可迭代对象(在Python 2中它返回list
)。让我为你的例子添加一些输出:
In [6]: nums = [1, 2, 3]
In [7]: for x in [4, 5, 6]:
...: nums = map(lambda n: n if x % 2 else n + 10, nums)
...: print(x)
...: print(nums)
...:
4
<map object at 0x7ff5e5da6320>
5
<map object at 0x7ff5e5da63c8>
6
<map object at 0x7ff5e5da6400>
In [8]: print(x)
6
In [9]: list(nums)
Out[9]: [31, 32, 33]
注意In[8]
- x
的值为6.我们还可以转换lambda
函数,传递给map
以跟踪{{1}的值1}}:
x
因为In [10]: nums = [1, 2, 3]
In [11]: for x in [4, 5, 6]:
....: nums = map(lambda n: print(x) or (n if x % 2 else n + 10), nums)
....:
In [12]: list(nums)
6
6
6
6
6
6
6
6
6
Out[12]: [31, 32, 33]
是惰性的,它会评估何时调用map
。但是,list
的值为x
,这就是产生混乱输出的原因。评估循环内的6
会产生预期的输出。
nums
答案 1 :(得分:5)
问题与您正在创建的lambda函数如何访问x
变量有关。 Python的作用域的工作方式,lambda函数在被调用时将始终使用来自外部作用域的最新版x
,而不是它们被定义时的值。
由于map
是惰性的,因此直到循环之后才会调用lambda函数(当你通过将嵌套map
传递给list
时使用嵌套x
)时,它们会被调用全部使用最后x
值。
要使每个lambda函数保存x=x
定义的值,请像这样添加lambda n, x=x: n if x % 2 else n + 10
:
x
指定参数及其默认值。默认值将在定义lambda时进行计算,因此当稍后调用lambda(没有第二个参数)时,表达式中的 $query = "SELECT pass FROM social WHERE id = 11"; // took the (``) out of the query and added this im assuming the value is stored in the $row variable and I may be able to use $row with the user input to verify hash via bcrypt!!!
$result = $conn->query($query);
while($row = mysqli_fetch_array($result))
{
echo $row['pass'];
echo "<br />";
}
将是保存的默认值。
答案 2 :(得分:3)
如果您想使用延迟版本,则需要在每个循环中修复x
。
functools.partial正是这样做的:
from functools import partial
def myfilter(n, x):
return n if x % 2 else n + 10
nums = [1, 2, 3]
for x in [4, 5, 6]:
f = partial(myfilter, x=x)
nums = map(f, nums)
>>> list(nums)
[21, 22, 23]