Il s'agit plutôt d'une réponse à Python 3.41 Un ensemble avant qu'elle ne soit fermée en tant que doublon.
Les autres ont raison : ne vous fiez pas à l'ordre. Ne prétendez même pas qu'il y en a un.
Cela dit, il y a un sur laquelle vous pouvez compter :
list(myset) == list(myset)
C'est-à-dire que l'ordre est stable .
Comprendre pourquoi il y a un perception de commander nécessite de comprendre certaines choses :
-
Ce Python utilise jeux de hachage ,
-
Comment l'ensemble de hachage de CPython est stocké dans la mémoire et
-
Comment les numéros sont hachés
Du haut en bas :
A jeu de hachage est une méthode de stockage de données aléatoires avec des temps de consultation très rapides.
Il a une matrice de sauvegarde :
# A C array; items may be NULL,
# a pointer to an object, or a
# special dummy object
_ _ 4 _ _ 2 _ _ 6
Nous ne tiendrons pas compte de l'objet fictif spécial, qui n'existe que pour faciliter la gestion des suppressions, car nous ne retirerons rien de ces ensembles.
Pour obtenir une recherche vraiment rapide, il faut calculer par magie un hachage à partir d'un objet. La seule règle est que deux objets qui sont égaux ont le même hash. (Mais si deux objets ont le même hachage, ils peuvent être inégaux).
Vous faites ensuite l'index en prenant le modulus par la longueur du tableau :
hash(4) % len(storage) = index 2
L'accès aux éléments est ainsi très rapide.
Les hachages ne représentent qu'une grande partie de l'histoire, car hash(n) % len(storage)
y hash(m) % len(storage)
peuvent aboutir au même nombre. Dans ce cas, plusieurs stratégies différentes peuvent essayer de résoudre le conflit. CPython utilise le "sondage linéaire" 9 fois avant de faire des choses compliquées, ainsi il aura l'air de à gauche de la fente jusqu'à 9 places avant de chercher ailleurs.
Les ensembles de hachage de CPython sont stockés comme ceci :
-
Un ensemble de hachage peut être pas plus de 2/3 plein . S'il y a 20 éléments et que le tableau de sauvegarde fait 30 éléments, le tableau de sauvegarde sera redimensionné pour être plus grand. En effet, les collisions sont plus fréquentes avec les petits backing stores, et les collisions ralentissent tout.
-
Le backing store se redimensionne par puissances de 4, en commençant par 8, sauf pour les grands ensembles (50k éléments) qui se redimensionnent par puissances de deux : (8, 32, 128, ...).
Ainsi, lorsque vous créez un tableau, le backing store est de longueur 8. Lorsqu'il est rempli à 5 et que vous ajoutez un élément, il contiendra brièvement 6 éléments. 6 > ²·8
ce qui déclenche un redimensionnement, et le backing store quadruple pour atteindre la taille 32.
Enfin, hash(n)
juste des retours n
pour les chiffres (sauf -1
ce qui est spécial).
Alors, regardons le premier :
v_set = {88,11,1,33,21,3,7,55,37,8}
len(v_set)
est 10, donc le magasin de sauvegarde est au moins 15(+1) après que tous les éléments aient été ajoutés . La puissance de 2 pertinente est 32. Donc le magasin de sauvegarde est :
__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
Nous avons
hash(88) % 32 = 24
hash(11) % 32 = 11
hash(1) % 32 = 1
hash(33) % 32 = 1
hash(21) % 32 = 21
hash(3) % 32 = 3
hash(7) % 32 = 7
hash(55) % 32 = 23
hash(37) % 32 = 5
hash(8) % 32 = 8
donc ces inserts comme :
__ 1 __ 3 __ 37 __ 7 8 __ __ 11 __ __ __ __ __ __ __ __ __ 21 __ 55 88 __ __ __ __ __ __ __
33 Can't also be where 1 is;
either 1 or 33 has to move
On s'attendrait donc à un ordre comme
{[1 or 33], 3, 37, 7, 8, 11, 21, 55, 88}
avec le 1 ou 33 qui n'est pas au début quelque part ailleurs. On utilisera un sondage linéaire, donc on aura soit :
__ 1 33 3 __ 37 __ 7 8 __ __ 11 __ __ __ __ __ __ __ __ __ 21 __ 55 88 __ __ __ __ __ __ __
o
__ 33 1 3 __ 37 __ 7 8 __ __ 11 __ __ __ __ __ __ __ __ __ 21 __ 55 88 __ __ __ __ __ __ __
On pourrait s'attendre à ce que le 33 soit celui qui est déplacé parce que le 1 était déjà là, mais en raison du redimensionnement qui se produit lors de la construction du jeu, ce n'est pas vraiment le cas. Chaque fois que le jeu est reconstruit, les éléments déjà ajoutés sont effectivement réorganisés.
Maintenant vous pouvez voir pourquoi
{7,5,11,1,4,13,55,12,2,3,6,20,9,10}
pourrait être en ordre. Il y a 14 éléments, donc le magasin de sauvegarde est au moins 21+1, ce qui signifie 32 :
__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
1 à 13 hachages dans les 13 premiers emplacements. 20 va dans l'emplacement 20.
__ 1 2 3 4 5 6 7 8 9 10 11 12 13 __ __ __ __ __ __ 20 __ __ __ __ __ __ __ __ __ __ __
55 va dans la fente hash(55) % 32
qui est de 23 :
__ 1 2 3 4 5 6 7 8 9 10 11 12 13 __ __ __ __ __ __ 20 __ __ 55 __ __ __ __ __ __ __ __
Si nous choisissons 50 à la place, nous nous attendons à ce que
__ 1 2 3 4 5 6 7 8 9 10 11 12 13 __ __ __ __ 50 __ 20 __ __ __ __ __ __ __ __ __ __ __
Et voilà :
{1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 20, 50}
#>>> {1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 50, 20}
pop
est implémenté assez simplement à première vue : il parcourt la liste et ouvre le premier.
Il s'agit de détails de mise en œuvre.