Wim Vogelaar said:
why this output isn't ordered, giving:
{2: 3, 4: 5, 6: 7, 8: 9, 10: 11 }
I made the original list two elements longer: a =
[1,2,3,4,5,6,7,8,9,10,11,12]
and to my surprise the output is now ordered, giving: {2: 3, 4: 5, 6:
7, 8: 9, 10: 11, 12: 13}
.... and it will become unordered again when you get up to storing 32 in the
dictionary, and ordered again when you get up to 44.
It is an unfortunate side-effect of the way that Python dictionaries work
that it often appears when you store small integers as though they are
being stored sorted. In fact the order depends on the order in which you
inserted the values into the dictionary, the current size allocated to the
dictionary, and whether any slots have previously been occupied by other
values.
In your original output:
{8: 9, 2: 3, 4: 5, 10: 11, 6: 7}
the keys 2, 4, and 6 are inserted into the 2nd, 4th, 6th slots of the
dictionary (counting from 0 and there are initially 8 slots), 8 goes into
the 0th slot, 10 would go into the 2nd slot except that is filled so it
ends up in the 5th slot.
When you insert 12, the initial dictionary is too full (it never fills all
the slots), so it is resized to have 32 slots. Again the 32 wraps round to
the 0th slot and higher values all collide with filled slots so they end up
in less obvious positions:
print dict.fromkeys(range(2,i,2))
{8: None, 2: None, 4: None, 10: None, 6: None}
{2: None, 4: None, 6: None, 8: None, 10: None, 12: None}
{2: None, 4: None, 6: None, 8: None, 10: None, 12: None, 14: None}
{2: None, 4: None, 6: None, 8: None, 10: None, 12: None, 14: None, 16:
None}
{2: None, 4: None, 6: None, 8: None, 10: None, 12: None, 14: None, 16:
None, 18: None}
{2: None, 4: None, 6: None, 8: None, 10: None, 12: None, 14: None, 16:
None, 18: None, 20: None}
{2: None, 4: None, 6: None, 8: None, 10: None, 12: None, 14: None, 16:
None, 18: None, 20: None, 22: None}
{2: None, 4: None, 6: None, 8: None, 10: None, 12: None, 14: None, 16:
None, 18: None, 20: None, 22: None, 24: None}
{2: None, 4: None, 6: None, 8: None, 10: None, 12: None, 14: None, 16:
None, 18: None, 20: None, 22: None, 24: None, 26: None}
{2: None, 4: None, 6: None, 8: None, 10: None, 12: None, 14: None, 16:
None, 18: None, 20: None, 22: None, 24: None, 26: None, 28: None}
{2: None, 4: None, 6: None, 8: None, 10: None, 12: None, 14: None, 16:
None, 18: None, 20: None, 22: None, 24: None, 26: None, 28: None, 30: None}
{32: None, 2: None, 4: None, 6: None, 8: None, 10: None, 12: None, 14:
None, 16: None, 18: None, 20: None, 22: None, 24: None, 26: None, 28: None,
30: None}
{32: None, 2: None, 4: None, 6: None, 8: None, 10: None, 12: None, 34:
None, 14: None, 16: None, 18: None, 20: None, 22: None, 24: None, 26: None,
28: None, 30: None}
{32: None, 2: None, 4: None, 6: None, 8: None, 10: None, 12: None, 34:
None, 14: None, 16: None, 18: None, 20: None, 22: None, 24: None, 36: None,
26: None, 28: None, 30: None}
{32: None, 2: None, 4: None, 38: None, 6: None, 8: None, 10: None, 12:
None, 34: None, 14: None, 16: None, 18: None, 20: None, 22: None, 24: None,
36: None, 26: None, 28: None, 30: None}
The fact that integers hash to themselves may be unlikely to change, but
the sizes of the hash tables, or the conflict resolution strategy when an
insertion hits an already used slot could all vary in other versions of
Python.