Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Non-deterministic set ordering

156 views
Skip to first unread message

Rob Cliffe

unread,
May 15, 2022, 11:01:39 PM5/15/22
to
I was shocked to discover that when repeatedly running the following
program (condensed from a "real" program) under Python 3.8.3

for p in { ('x','y'), ('y','x') }:
    print(p)

the output was sometimes

('y', 'x')
('x', 'y')

and sometimes

('x', 'y')
('y', 'x')

Can anyone explain why running identical code should result in
traversing a set in a different order?
Thanks
Rob Cliffe

Dan Stromberg

unread,
May 15, 2022, 11:13:40 PM5/15/22
to
Sets are defined as unordered so that they can be hashed internally to give
O(1) operations for many tasks.

It wouldn't be unreasonable for sets to use a fixed-by-arbitrary ordering
for a given group of set operations, but being unpredictable deters
developers from mistakenly assuming they are ordered.

If you need order, you should use a tuple, list, or something like
https://grantjenks.com/docs/sortedcontainers/sortedset.html

Rob Cliffe

unread,
May 15, 2022, 11:21:16 PM5/15/22
to
Thanks, I can work round this behaviour.
But I'm curious: where does the variability come from?  Is it deliberate
(as your answer seems to imply)?  AFAIK the same code within the *same
run* of a program does produce identical results.
Best wishes
Rob Cliffe

Paul Bryan

unread,
May 15, 2022, 11:36:54 PM5/15/22
to

Rob Cliffe

unread,
May 15, 2022, 11:41:20 PM5/15/22
to
Thanks, Paul.  Question answered!
Rob Cliffe

MRAB

unread,
May 15, 2022, 11:43:46 PM5/15/22
to
Basically, Python uses hash randomisation in order to protect it against
denial-of-service attacks. (Search for "PYTHONHASHSEED" in the docs.)

It also applied to dicts (the code for sets was based on that for
dicts), but dicts now remember their insertion order.
0 new messages