Different Random Numbers Between Already/Not Yet Compiled Code

Tim Peters tim.one at home.com
Thu Jan 24 21:54:01 CET 2002


[Eric Eide]
> Short story: `random' turned out not to be the trouble at all.

It never is <wink>.  Glad you're unstuck!

> After some investigation, I discovered the reason for the
> difference between the output of my compiled and non-compiled Python
> program: it was due to getting different arrangements of tuples from
> the dictonary `items' method.

I hate to be optimistic, but that's almost as mysterious.  While Python
doesn't define anything about the order of entries in dict.items(), provided
the dict doesn't change it's the same every time you call it, and consistent
with the order of dict.keys() and dict.values() (which are basically
projections of dict.items(), removing one or the other of each (key, value)
pair).

> When my simulation program iterated over the list returned by `items', it
> applied a predictable series of random numbers to an unpredictable
> arrangement of my objects, thus yielding unpredictable results.

I'd sure like to see a concrete example.  The only semi-plausible cause I
can think of is if your keys are instances of a class that doesn't define
__hash__; then they're hashed by raw memory addresses, and those can vary
for all sorts of reasons -- even *across* runs of your program, all from
.pyc or all from .py.  If a .py->.pyc compilation is done, the memory layout
can change as a side-effect of doing the compilation, and that would make a
different order more likely.  But even if no .py->.pyc step is needed, the
system malloc() doesn't guarantee to return the same memory addresses across
runs.

> Sorting the returned `items' list before iterating over it solved my
> unpredictability problem,

A good solution -- unless you're merely sorting by the keys' memory
addresses (and then this problem will come up again, sooner or later).





More information about the Python-list mailing list