0

Here is a simple program that appends integers to a set in Python 3:

s = set()
for i in range(10):
    s.add(i*47)

Naturally I would expect the result to be: 0 47 94 141 188 235 282 329 376 423

In fact, the result is: 0 423 329 235 141 47 376 282 188 94

So the output is re-ordered in some way that is not consistent. It's not sorted or reordered in any way I can intuit.

I've done research but I haven't found an answer to this simple question. When I use set.add, in what order are the elements added? How and why are they re-sorted this way?

RTC222
  • 2,025
  • 1
  • 20
  • 53
  • 3
    Sets are inherently unordered data structures. You should not think of them as having *any order*, and and you shouldn't rely on the particular order you observe, because it will be an implementation detail – juanpa.arrivillaga May 22 '18 at 22:55
  • 1
    Sets are arbitrarily ordered. In some cases, Python will even go out of its way to make sure you can't intuit the order (as a side effect of going out of its way to make sure bad guys can't intuit the order of dicts on your web server). – abarnert May 22 '18 at 22:55
  • If you want something that acts like a set but preserves addition order (the same way `collections.OrderedDict` acts like a dict but preserves insertion order), your question is probably a duplicate of [this one](https://stackoverflow.com/questions/1653970/). If you instead want something different (a sorted set, or an explanation for why Python sets are designed this way, or something like that), you can clarify that by editing your question. – abarnert May 22 '18 at 22:56
  • Also, how much research did you do? The docs for [`set`](https://docs.python.org/3/library/stdtypes.html#set-types-set-frozenset) start off "A *set* object is an unordered collection of…", and repeat that with more details a couple times below. – abarnert May 22 '18 at 22:58
  • There is a better dupe somewhere, where somebody (Martijn?) actually showed why/how/when the sets would get shuffled after mutation. – wim May 22 '18 at 22:59
  • @wim My linked dup is only right if the OP's real question is "how do I get a set to preserve insertion order?" (Which is why I asked instead of voting to close/dup-hammering…) – abarnert May 22 '18 at 23:00
  • Yes, I saw that sets are unordered, but that doesn't mean that it re-orders the set as I am adding them in. – RTC222 May 22 '18 at 23:00
  • I can't find it now, but this is similar: ['order' of unordered Python sets](https://stackoverflow.com/q/12165200/674039) – wim May 22 '18 at 23:03
  • 1
    @RTC222 It doesn't necessarily re-order the set as you're adding them in. And, even if some particular version of CPython happens to do that in your test case, you can't rely on that, any more than you can rely on the fact that it _doesn't_ do so. Being unordered mean that the order at any given time is completely meaningless, and therefore any code you write that relies on the order is wrong. – abarnert May 22 '18 at 23:10
  • Thanks very much. That answers my question. – RTC222 May 22 '18 at 23:11

0 Answers0