Reputation: 3174
I was writing a sudoku solver, and came across this weird behavior. If I do the following:
r = range(1,len(board)+1)
b = block(board,x,y)
nums = [x for x in r if x not in b]
nums
will be different from this way of calculating it:
nums = [x for x in range(1,len(board)+1) if x not in block(board,x,y)]
The block
is simply as follows:
return sum([col[y*N(board):(y+1)*N(board)]
for col in board[x*N(board):(x+1)*N(board)]],
[])
Where N
is just the square-root of the size of the board, and board is just a list of lists of numbers. (The reason for things like N
and len
all over the place is that it should work for boards that aren't 9x9 too)
My question is simply: Why could these things be different? It's just reading values and storing them in variables, not assigning anything to board itself, so why would it matter if I do b = a
and then use a
, or just use b
to begin with?
Upvotes: 3
Views: 58
Reputation: 29710
When you use
r = range(1,len(board)+1)
b = block(board,x,y)
nums = [x for x in r if x not in b]
x
is most likely already set to some constant, hence b
becomes constant in your list comprehension. When you use your second list comprehension, x
has a different value (iterating over r
) throughout the comprehension, and overrides whatever x
is on your function or module level - hence every check if x
is in block(board,x,y)
becomes dependent on your comprehension iteration.
Give your list comprehension variable a different name than x
, and be careful about overwriting variable names.
Here's a minimal example where you can see that the variable name x
is overwritten, and how it affects each call to your function.
>>> 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)]
[]
Upvotes: 3
Reputation: 336408
In the first example, b
is calculated to be block(board,x,y)
, using whatever value x
has at that moment. This value is then reused for all the iterations of the following list comprehension.
In the second example, x
changes throughout the list comprehension, so with each iteration, block(board,x,y)
will return a different result.
Upvotes: 3