2016-05-21 24 views
3

我正在写一个数独求解器,并遇到了这个奇怪的行为。如果我做到以下几点:为什么这些看起来相同的代码片段的行为有所不同? (Python 3)

r = range(1,len(board)+1) 
b = block(board,x,y) 
nums = [x for x in r if x not in b] 

nums将是这样计算它的不同:

nums = [x for x in range(1,len(board)+1) if x not in block(board,x,y)] 

block很简单如下:

return sum([col[y*N(board):(y+1)*N(board)] 
      for col in board[x*N(board):(x+1)*N(board)]], 
      []) 

哪里N只是董事会规模的平方根,董事会只是一个数字清单的列表。 (之所以像Nlen到处都是它应该适用于不是9x9的板子)

我的问题很简单:为什么这些东西会不一样?它只是读取值并将它们存储在变量中,而不是将任何东西分配给板本身,所以如果我做b = a然后使用a或仅使用b开始时为什么会这样?

+2

在第一种情况下'x'是什么?在第二种情况下,你至少要重写列表理解变量'x'。 – miradulo

+1

我假设你的'block'函数返回某物。第二个版本的每次调用都不同,基于'x'的变化,其中'b'在第一个中始终保持相同。 – schwobaseggl

+0

他们说什么。请注意,第二个版本不必要地重新计算'block(board,x,y)'len(board)'次。 –

回答

3

在第一个示例中,b计算为block(board,x,y),使用任何值x在此刻具有。这个值然后被重复用于以下列表理解的所有迭代。

在第二个示例中,x在整个列表理解中发生变化,因此每次迭代时,block(board,x,y)将返回不同的结果。

+0

我在问自己,我是如何忽略这一点的,这很明显。谢谢! – Wysaard

3

当您使用

r = range(1,len(board)+1) 
b = block(board,x,y) 
nums = [x for x in r if x not in b] 

x是最有可能已经被设置为某个常数,因此b成为您的列表理解不变。当你使用第二个列表理解时,x在整个理解中具有不同的值(遍历r),并且覆盖功能或模块级别的任何x - 因此每次检查x是否在block(board,x,y)中变得依赖于理解迭代。

给你的列表理解变量使用与x不同的名称,并且注意覆盖变量名称。


这里有一个小例子,在这里你可以看到变量名x被覆盖,以及它如何影响每个调用你的函数。

>>> r = range(5) 
>>> x = 1 
>>> b = range(x+1) 
>>> [x for x in r if x not in b] 
[2, 3, 4] 
>>> [x for x in range(5) if x not in range(x+1)] 
[] 
相关问题