C'est plus une réponse à Python 3.41 Un ensemble avant qu'il ne soit fermé en tant que doublon.
Les autres ont raison: ne vous fiez pas à la commande. Ne prétendez même pas qu'il y en a un.
Cela dit, il y a une chose sur laquelle vous pouvez compter:
list(myset) == list(myset)
Autrement dit, l'ordre est stable .
Comprendre pourquoi il y a un ordre perçu nécessite de comprendre certaines choses:
Que Python utilise des ensembles de hachage ,
Comment l'ensemble de hachage de CPython est stocké en mémoire et
Comment les nombres sont hachés
Du haut:
Un ensemble de hachage est une méthode de stockage de données aléatoires avec des temps de recherche très rapides.
Il a un réseau de support:
# A C array; items may be NULL,
# a pointer to an object, or a
# special dummy object
_ _ 4 _ _ 2 _ _ 6
Nous ignorerons l'objet factice spécial, qui n'existe que pour faciliter la gestion des suppressions, car nous ne supprimerons pas de ces ensembles.
Afin d'avoir une recherche très rapide, vous faites de la magie pour calculer un hachage à partir d'un objet. La seule règle est que deux objets égaux ont le même hachage. (Mais si deux objets ont le même hachage, ils peuvent être inégaux.)
Vous faites ensuite en index en prenant le module par la longueur du tableau:
hash(4) % len(storage) = index 2
Cela rend l'accès aux éléments très rapide.
Les hachages ne sont que l'essentiel de l'histoire, car hash(n) % len(storage)
et hash(m) % len(storage)
peuvent aboutir au même nombre. Dans ce cas, plusieurs stratégies différentes peuvent tenter de résoudre le conflit. CPython utilise le «sondage linéaire» 9 fois avant de faire des choses compliquées, il regardera donc à gauche de l'emplacement jusqu'à 9 endroits avant de chercher ailleurs.
Les ensembles de hachage de CPython sont stockés comme ceci:
Un ensemble de hachage ne peut pas être rempli à plus des 2/3 . S'il y a 20 éléments et que le tableau de sauvegarde a une longueur de 30 éléments, le magasin de sauvegarde sera redimensionné pour être plus grand. En effet, vous obtenez plus souvent des collisions avec de petits magasins de support, et les collisions ralentissent tout.
Le magasin de support se redimensionne par puissances de 4, à partir de 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 magasin de stockage a une longueur de 8. Lorsqu'il est plein à 5 et que vous ajoutez un élément, il contiendra brièvement 6 éléments. 6 > ²⁄₃·8
Cela déclenche donc un redimensionnement et le magasin de support quadruple à la taille 32.
Enfin, hash(n)
retourne juste n
pour les nombres (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 égal à 10, donc le magasin auxiliaire est au moins 15 (+1) après que tous les éléments ont été ajoutés . La puissance pertinente de 2 est 32. Ainsi, le magasin de support 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 ceux-ci insèrent 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
Nous nous attendrions donc à une commande comme
{[1 or 33], 3, 37, 7, 8, 11, 21, 55, 88}
avec le 1 ou 33 qui n'est pas au départ ailleurs. Cela utilisera un sondage linéaire, donc nous aurons soit:
↓
__ 1 33 3 __ 37 __ 7 8 __ __ 11 __ __ __ __ __ __ __ __ __ 21 __ 55 88 __ __ __ __ __ __ __
ou
↓
__ 33 1 3 __ 37 __ 7 8 __ __ 11 __ __ __ __ __ __ __ __ __ 21 __ 55 88 __ __ __ __ __ __ __
Vous pourriez vous attendre à ce que le 33 soit celui qui a été déplacé parce que le 1 était déjà là, mais en raison du redimensionnement qui se produit lors de la construction de l'ensemble, ce n'est pas le cas. Chaque fois que l'ensemble est reconstruit, les éléments déjà ajoutés sont effectivement réorganisés.
Maintenant tu peux 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 support est au moins 21 + 1, ce qui signifie 32:
__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
1 à 13 hachage 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 23:
__ 1 2 3 4 5 6 7 8 9 10 11 12 13 __ __ __ __ __ __ 20 __ __ 55 __ __ __ __ __ __ __ __
Si nous choisissions 50 à la place, nous nous attendrions à
__ 1 2 3 4 5 6 7 8 9 10 11 12 13 __ __ __ __ 50 __ 20 __ __ __ __ __ __ __ __ __ __ __
Et voici:
{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é tout simplement par l'apparence des choses: il parcourt la liste et fait apparaître le premier.
Ce sont tous les détails de mise en œuvre.