On 12/31/2013 06:59 AM, Keith Winston wrote:
I resolved a problem I was having with lists, but I don't understand how! I
caught my code inadvertently resetting/zeroing two lists TWICE at the
invocation of the game method, and it was leading to all the (gamechutes &
gameladders) lists returned by that method being zeroed out except the
final time the method is called. That is: the game method below is iterated
iter times (this happens outside the method), and every time gamechutes and
gameladders (which should be lists of all the chutes and ladders landed on
during the game) were returned empty, except for the last time, in which
case they were correct. I can see that doing the multiple zeroing is
pointless, but I can't understand why it would have any effect on the
returned values. Note that self.reset() is called in __init__, so the lists
exist before this method is ever called, if I understand properly.
def game(self, iter):
"""Single game"""
self.gamechutes[:] = [] #when I take out these two slice
assignments,
self.gameladders[:] = [] # then gamechutes & gameladders work
properly
self.gamechutes = [] # these were actually in a call to
self.reset()
self.gameladders = []
#.... other stuff in reset()
while self.position < 100:
gamecandl = self.move()
if gamecandl[0] != 0:
self.gamechutes.append(gamecandl[0])
if gamecandl[1] != 0:
self.gameladders.append(gamecandl[1])
return [iter, self.movecount, self.numchutes, self.numladders,
self.gamechutes, self.gameladders]
I'm happy to share the rest of the code if you want it, though I'm pretty
sure the problem lies here. If it's not obvious, I'm setting myself up to
analyse chute & ladder frequency: how often, in a sequence of games, one
hits specific chutes & ladders, and related stats.
As always, any comments on style or substance are appreciated.
Well you have found the reason for weird behaviour, but there is one point you
may have missed, I mean not fully understood, else you would probably never have
coded that way.
Imagine there is somewhere in your code, before the resetting of either, some
reference to this list; then you empty this list using the first idiom, the
emptying instruction with [:], like:
original = [1, 2, 3]
# ...
ref_to_list = original # not a copy
# ...
original[:] = [] # empty the same list
# assert checks something is true; else we get an AssertionError:
assert(ref_to_list is original)
assert(ref_to_list == [])
Now, replace the emptying instruction with:
original = [] # assigns another list
Now, assertions are false (both). `ref_to_list` actually still refers to the...
original list; The folllowing is true in this version:
assert(ref_to_list == [1,2,3])
But the symbol `original` itself is not bound to this orignal list anymore (it's
now a liar! a misnomer). In this version, we do not *modify* the list element
(to empty it, for the matter), but *replace* it by a new one (empty right from
the start), bound to `original`.
And as you ask for style comments, I would (this is subject to personal views):
* use '_' for multi-word ids: game_chutes
* say what the 'game' method computes and returns, in comment/doc and in its
*name*
(many think a true function, that produces a result, should be named after
its product
-- I share this view -- eg 'square' compute the square of its input)
* 'iter' is a clear misnomer: I would have never guessed if you didn't say it in
text:
use eg n_iters or number_iters or such [*]
(
Denis
[*] In addition, "iter" is also the name of a builtin function, like "print". It
is rarely a good idea to reuse such names, but maybe you did not know it. Here
is what it does (if you don't know yet about iterator objects, this will give
you a fore-taste, but don't bother with that topic before you actually need them):
spir@ospir:~$ python3
Python 3.3.1 (default, Sep 25 2013, 19:29:01)
[GCC 4.7.3] on linux
Type "help", "copyright", "credits" or "license" for more information.
iter
<built-in function iter>
l = [1,2,3]
it = iter(l)
it
<list_iterator object at 0x7f5a63b41c50>
for i in it: print(i)
...
1
2
3
_______________________________________________
Tutor maillist - Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor