-1

I don't understand why set() works the way it does...

Let's say we have two lists:

a = [1,2,-1,20,6,210,1, -11.4, 2]
b = [1,2,-1,20,6,210,1,-11.4, 2, "a"]

When I run set() on the list of numerics, a, I get a set of unique numerics ordered from smallest to largest. Ok great, that seems intuitive! Haven't found any exceptions yet:

set(a)
Out: {-11.4, -1, 1, 2, 6, 20, 210}

What happens if I throw a character in like with list b? Weirdness. The negatives are out of order and so is 6.

set(b)
Out: {-1, -11.4, 1, 2, 20, 210, 6, 'a'}

It gets worse though. What if I try to turn those sets back into lists? Pure chaos.

list(set(a))
Out: [1, 2, 6, 210, 20, -11.4, -1]

list(set(b))
Out: [1, 2, 6, 'a', 210, 20, -11.4, -1]

As you can see, these lists indeed only have unique values. But have failed to preserve much semblance of the order of the original lists.

What's going on here and why?

Nova
  • 588
  • 4
  • 16
  • I know 'a' is ascii 97, that would put it in numerical ordering, however I dont believe the documentation guarantees the set is ordered. – Kevin Crum Feb 11 '21 at 21:02
  • 4
    Sets, in most languages, are unordered. Any perceived order is a consequence of the implementation and shouldn't be relied on unless the set is explicitly indicated to be ordered. – Carcigenicate Feb 11 '21 at 21:03
  • 1
    btw your list `b` does not contain `-11.4`. And I'm not sure that anything you have asserted is actually true. – quamrana Feb 11 '21 at 21:05
  • " I get a set of unique numerics ordered from smallest to largest. Ok great, that seems intuitive! " No, it isn't. Your intution is that *sets don't have order*, because python sets are *hash sets*. Any order you happen to see is the result of implementation details. – juanpa.arrivillaga Feb 11 '21 at 21:06
  • It behaves strangely because it hasn't made any promises to behave predictably re: order. It's an unordered type. If you want to get order out of a set, try `sorted(set(b))` which will give you a list. – MatrixManAtYrService Feb 11 '21 at 21:07
  • As everyone has said, the order of sets is not assured, its just coincident. Order also is subjective. If your values are ordered by a stringwise implementation then 100 for example would come before 19 etc – Chris Doyle Feb 11 '21 at 21:09

1 Answers1

4

The set type in python is not explicitly ordered. It can appear ordered based on the implementation, but is not guaranteed to be so. If you need a ordered representation, you should use something like sorted(set(input_sequence)) which will return a sorted list after removing the duplicates. Note that sorting lists with types that are not comparable is not supported without some sort of custom comparator (so you can't sort ['a', 1] out of the box).

g.d.d.c
  • 46,865
  • 9
  • 101
  • 111
  • 1
    I'll do you one better: the docs explicitly say "[A set is an unordered collection](https://docs.python.org/3/tutorial/datastructures.html#sets)". Python doesn't just say "this may not be ordered", but that they definitely aren't. – Kirk Strauser Feb 11 '21 at 21:11