I wrote this code:
s = set(range(10))
print(s)
but every time the result is {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
.
aren't sets unordered?
The set in this code is always ordered but not indexed.
I wrote this code:
s = set(range(10))
print(s)
but every time the result is {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
.
aren't sets unordered?
The set in this code is always ordered but not indexed.
No, usually not.
>>> s = {8, 4, 0}
>>> print(s)
{8, 0, 4}
With set(range(n))
, in current CPython, they're sorted because every number i
gets placed at index i
in the hash table. Because for example with n=20, the hash table gets 32 rows and number i
gets mapped to hash(i) % 32
= i % 32
= i
. So when that table is iterated, you get the numbers sorted. But it's an implementation detail, so don't rely on it.
Better demonstration, btw, also showing that it's not ordered in "insertion order" or so, but really gets sorted:
>>> from random import shuffle
>>> a = list(range(20))
>>> shuffle(a)
>>> a
[14, 15, 5, 17, 3, 18, 16, 7, 8, 19, 2, 10, 12, 6, 1, 9, 11, 4, 0, 13]
>>> set(a)
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}
With my above {8, 4, 0}
, the hash table has 8 rows and so 8
gets mapped to hash(8) % 8
= 8 % 8
= 0
and thus gets put into row 0. Then 4
gets put into row 4. Then 0
ought to go into row 0, but since that's already occupied, it must go somewhere else and apparently ends up between the numbers 8
and 4
, i.e., in one of the rows 1, 2 or 3.
Visually:
Initial After After After
empty placing placing placing
table: the 8: the 4: the 0:
0: 0: 8 0: 8 0: 8
1: 1: 1: 1: 0 (or could be at place 2 or 3)
2: 2: 2: 2:
3: 3: 3: 3:
4: 4: 4: 4 4: 4
5: 5: 5: 5:
6: 6: 6: 6:
7: 7: 7: 7: