[Tutor] Improving My Simple Game Code for Speed, Memory and Learning
Steven D'Aprano
steve at pearwood.info
Sun Jan 4 11:07:35 CET 2015
On Sat, Jan 03, 2015 at 09:57:20PM -0500, Dave Angel wrote:
> On 01/03/2015 06:10 PM, WolfRage wrote:
> >On 01/03/2015 04:42 PM, Dave Angel wrote:
> >>self.transposed_grid = list( zip(*self.grid) )
> >This results in the same thing with or with out the list() wrapper. Using
> >Python 3.4.0 (default, Apr 11 2014, 13:05:11)
> >[GCC 4.8.2] on linux
>
> In Python 3, zip() returns an iterator. So you can traverse it once. I
> don't believe the second time is guaranteed to be the same. A list is
> what you want.
You cannot traverse iterators twice. Once they are exhausted, they stay
exhausted. Technically you can write an iterator that can be re-used,
but according to the iterator specification that is officially called
"broken".
Specifically in the case of zip, if its arguments are sequences such as
lists or tuples, then you can call zip(a, b) twice and the resulting
iterator will always be in the same order. But if the arguments are sets
or dicts, then Dave is correct, the language does not guarantee that the
zip iterator will have the same order each time. But that's not because
of zip(), that's because the order of sets and dicts is not guaranteed
to be the same each time.
That is, given a set some_set, if you make two lists from it:
a = list(some_set)
b = list(some_set) # The same set.
the language doesn't guarantee that a == b, as the order *could* be
different each time. But in practice, I don't know any Python
implementation *yet* where they actually are different, although I
expect that there will be in the future.
The reason is that there are some Denial Of Service attacks against
Python related to being able to predict the order of dictionaries.
Python 3.3 changes the order from one interpreter session to the next,
but that's not actually enough to prevent the DOS attack, so I expect
that future versions may eventually fully randomize the output:
Python 2.7 has an arbitrary, but predictable, output, which is the same
from one run to the next:
[steve at ando ~]$ python2.7 -c "print set(['ape', 'bat', 'cat', 'dog', 'fox'])"
set(['bat', 'cat', 'fox', 'dog', 'ape'])
[steve at ando ~]$ python2.7 -c "print set(['ape', 'bat', 'cat', 'dog', 'fox'])"
set(['bat', 'cat', 'fox', 'dog', 'ape'])
Python 3.3 changes the order from one run to the next:
[steve at ando ~]$ python3.3 -c "print({'ape', 'bat', 'cat', 'dog', 'fox'})"
{'cat', 'fox', 'dog', 'bat', 'ape'}
[steve at ando ~]$ python3.3 -c "print({'ape', 'bat', 'cat', 'dog', 'fox'})"
{'cat', 'ape', 'bat', 'fox', 'dog'}
--
Steve
More information about the Tutor
mailing list