Kris Schnee wrote:
Aha! I've seen a problem like this before. I called it the "stripey doom
error," because when I did a tile-based game and changed one element,
I'd see a whole stripe of tiles change instead of one. Python has other
"sticky variable" problems sometimes if you don't think carefully about
whether something is a reference to another variable. I would sometimes
end up changing "constants" and having other problems.
This has happened to me too and "stripey doom error" is a great name
for it :).
When all else fails, copy.deepcopy() seems to make Python understand, "I
want this to have _the same value_ as X now has, not to be a _reference_
to X."
When I was learning C++, and being taught how to write classes, we
were taught that some copies are shallow, and some copies are deep,
like with copy.deepcopy. A shallow copy is one that only copies one
level of stuff. So, for example:
l = [1, 'a', {}]
l2 = l[:] # make a shallow copy
l
[1, 'a', {}]
l2
[1, 'a', {}]
l2 [1] = 'b'
l
[1, 'a', {}]
l2
[1, 'b', {}]
l2 is a copy of l, and I can change it separately. But the elements of
l2 are the same as the elements in l (the same objects, not a copy) so
if I change the dictionary:
l2[-1]['a'] = 4
l2
[1, 'b', {'a': 4}]
l
[1, 'a', {'a': 4}]
... it changes in both. That's OK for your coords example, for
instance, because you aren't changing the integers (integers are
immutable), but changing the list that has those integers.
By comparison:
l = [1, 'a', {}]
l2 = copy.deepcopy(l)
l2[-1]['a'] = 4
l
[1, 'a', {}]
l2
[1, 'a', {'a': 4}]
For lists, you can use the [:] syntax, which creates a slice of the
whole object, to get a shallow copy. You can also use functions like:
copy_of_coords = list(coords)
copy_of_d = dict(d)
The code that generates "stripey doom errors" isn't really creating a
copy of the rows, but repeating the same row, so it isn't even a
shallow copy.
I hope this is useful! The problem, the symptoms and the solution have
already been posted but I thought I would add some Computer Science
Lore to spice things up a bit.
Ethan