1
votes

Create a set, cast it to a list. sort() and look at the result.

I expected a sorted list, but was greeted by a sorted SET. How did the results of sorting the list get back into the set?

 a={5,4,2,7}
 list(a).sort()
 a
 {2, 4, 5, 7}
4
It didn't. You didn't assign anything back to a.jonrsharpe
Outputting the set will look exactly the same without any soritng of unrelated lists.user2390182

4 Answers

3
votes

You do not have a "sorted set" as you think. A set is "sorted" into whatever order the underlying implementation finds convenient. For a dense set of small integers, the integer value is the hash key, so any such set will be "sorted" into ascending order. For more spaced integers, the ordering ... well, you can play with it to see some of the effects -- but conventional wisdom is simply not to depend on any particular order. You happened to pick a sufficiently dense set. {1, 2, 3, 8} will "sort" with the 8 at the front ... until you insert 5 and 7 as well.

Your sort call has nothing to do with this. Most of all, you didn't sort the set; you sorted a temporary list constructed from the set, sorted that list, and then threw the list away by not storing it into a variable.

To illustrate:

>>> num = {5, 2, 3, 7}
>>> num    # Naturally sorted
{2, 3, 5, 7}
>>> let = {'e', 'b', 'c', 'g'}
>>> let    # Sorted by string hash value
{'g', 'c', 'e', 'b'}
>>> list(let)
['g', 'c', 'e', 'b']
>>> list(let).sort()
>>> # Note that sort returns None
>>> sorted(list(let))   # THIS gets the list sorted by value
['b', 'c', 'e', 'g']
1
votes

Sets are implemented as hash tables and should be considered to be ordered arbitrarily.

When you create a set of number, it takes the hash of the numbers and uses that hash to determine where the numbers go in the hash table.

As you can see, sets do not care about the order of the elements they are given:

>>> {*range(100)}
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99}
>>> {*range(99, -1, -1)}
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99}

We can see that integers are usually hashed as their own value, but as -1 is hashed to be -2, we can also see that this is not necessarily the case:

>>> {i: hash(i) for i in range(-5, 6)}
{-5: -5, -4: -4, -3: -3, -2: -2, -1: -2, 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5}

It is just an implementation detail.

Sets are not ordered.

1
votes

How a set is displayed/printed really depends in the underlying implementation, and has nothing to do with you calling list(a).sort(). To demonstrate this, you can try printing a before and after sorting, and you should generally get the same result (still depends on the underlying implementation, though)

a={5,4,2,7}
print(a)
list(a).sort()
print(a)

Output:

{2, 4, 5, 7}
{2, 4, 5, 7}
-1
votes

In Python, a set is defined by {}, while a list is defined by []. If you wanted your sorted number to return as a list instead of a set, you would need to change your variable type to what I mentioned above. Your new code should be something like this:

a = [5, 4, 2, 7]
list(a).sort()

= [2, 4, 5, 7]