max([x代表某事物的x])vs max(x代表某事物的x):为什么会有差异,它是什么?

bob*_*bob 16 python list-comprehension python-2.7

我正在为一个类的项目工作,我的代码没有产生与参考代码相同的结果.

我将我的代码与参考代码逐行比较,它们看起来几乎完全相同.一切似乎在逻辑上等同.最终我开始更换线和测试,直到找到重要的线.

原来它是这样的(编辑:确切代码更低):

# my version:
max_q = max([x for x in self.getQValues(state)])

# reference version which worked:
max_q = max(x for x in self.getQValues(state))
Run Code Online (Sandbox Code Playgroud)

现在,这让我感到困惑.我尝试使用Python(2.7)解释器进行一些实验,使用max带有和不带方括号的列表推导运行测试.结果似乎完全一样.

即使通过PyCharm进行调试,我也没有理由认为我的版本没有产生与参考版本完全相同的结果.到目前为止,我认为我对列表理解的工作方式(以及max()函数的工作方式)有很好的处理,但现在我不太确定,因为这是一个如此奇怪的差异.

这里发生了什么?为什么我的代码产生的结果与参考代码不同(在2.7中)?没有括号的理解中的传递与传递括号的理解有何不同?

编辑2:确切的代码是这样的:

# works
max_q = max(self.getQValue(nextState, action) for action in legal_actions)

# doesn't work (i.e., provides different results)
max_q = max([self.getQValue(nextState, action) for action in legal_actions])
Run Code Online (Sandbox Code Playgroud)

我不认为这应该被标记为重复 - 是的,另一个问题是关于理解对象和列表对象之间的区别,但是max()当给出"由X理解构建的一些列表"时,为什么会提供不同的结果,而不是' X理解'独自一人.

Eri*_*ric 18

您是否泄漏了影响以后代码的局部变量?

# works
action = 'something important'
max_q = max(self.getQValue(nextState, action) for action in legal_actions)
assert action == 'something important'

# doesn't work (i.e., provides different results)
max_q = max([self.getQValue(nextState, action) for action in legal_actions])
assert action == 'something important'  # fails!
Run Code Online (Sandbox Code Playgroud)

生成器和字典理解创建了一个新的范围,但在py3之前,列表推导没有,为了向后兼容

简单的测试方法 - 将代码更改为:

max_q = max([self.getQValue(nextState, action) for action in legal_actions])
max_q = max(self.getQValue(nextState, action) for action in legal_actions)
Run Code Online (Sandbox Code Playgroud)

假设self.getQValue是纯粹的,那么第一行唯一持久的副作用就是混乱局部变量.如果这打破了,那么这就是问题的原因.

  • @andy注意:这与python2.x中的list-comprehensions是循环的语法糖,而生成器表达式创建一个新范围(因此不泄漏变量)这一事实有关.在python3中,您提供的两个示例*do*以相同的方式执行. (4认同)

Jar*_*key 7

使用[]列表推导实际上会生成一个列表到您的变量中,或者在这种情况下生成一个最大函数.如果没有括号,您将创建一个generator将被输入max函数的对象.

results1 = (x for x in range(10))
results2 = [x for x in range(10)]
result3 = max(x for x in range(10))
result4 = max([x for x in range(10)])
print(type(results1)) # <class 'generator'>
print(type(results2)) # <class 'list'>
print(result3) # 9
print(result4) # 9
Run Code Online (Sandbox Code Playgroud)

据我所知,它们应该在max函数中基本相同.