Récemment, j'ai remarqué que lorsque je convertis un list
en set
ordre des éléments, il est modifié et trié par caractère.
Prenons cet exemple:
x=[1,2,20,6,210]
print x
# [1, 2, 20, 6, 210] # the order is same as initial order
set(x)
# set([1, 2, 20, 210, 6]) # in the set(x) output order is sorted
Mes questions sont -
- Pourquoi cela arrive-t-il?
- Comment puis-je effectuer des opérations de définition (en particulier Définir la différence) sans perdre la commande initiale?
unique = list(dict.fromkeys([1, 2, 1]).keys())
. Cela fonctionne parce que l'dict
ordre d'insertion est conservé maintenant.Réponses:
A
set
est une structure de données non ordonnée, elle ne conserve donc pas l'ordre d'insertion.Cela dépend de vos besoins. Si vous avez une liste normale et que vous souhaitez supprimer un ensemble d'éléments tout en préservant l'ordre de la liste, vous pouvez le faire avec une compréhension de liste:
Si vous avez besoin d'une structure de données qui prend en charge à la fois les tests d'appartenance rapides et la préservation de l'ordre d'insertion , vous pouvez utiliser les clés d'un dictionnaire Python, qui à partir de Python 3.7 est garanti pour préserver l'ordre d'insertion:
b
n'a pas vraiment besoin d'être commandé ici - vous pouvez également utiliser unset
. Notez quea.keys() - b.keys()
renvoie la différence définie sous forme de aset
, donc il ne conservera pas l'ordre d'insertion.Dans les anciennes versions de Python, vous pouvez utiliser à la
collections.OrderedDict
place:la source
None
est une langue singleton garantie. En CPython, le coût réel n'est que le pointeur (bien que ce coût soit toujours là, mais pour un dict, vous pouvez presque considérerNone
et d'autres singletons ou références partagées "libres"), donc un mot machine, probablement 8 octets sur les ordinateurs modernes . Mais oui, ce n'est pas aussi peu encombrant qu'un ensemble pourrait l'être.dict.fromkeys([1, 2, 1]).keys()
parce que les réguliersdict
conservent également l'ordre.Dans Python 3.6,il existe une autre solution pour Python 2 et 3:set()
maintenant devrait garder l'ordre, maisla source
x.index
appel, une recherche linéaire est effectuée. Si vous êtes d'accord avec la complexité quadratique, il n'y a aucune raison d'utiliser aset
en premier lieu.set()
n'est pas commandé dans Python 3.6, même pas comme un détail d'implémentation, vous pensez àdict
sint
se hachent souvent eux-mêmes stackoverflow.com/questions/45581901x=[1,2,-1,20,6,210]
faire un ensemble. Vous verrez qu'il n'est pas du tout commandé, testé en Python 3.6.En réponse à votre première question, un ensemble est une structure de données optimisée pour les opérations d'ensemble. Comme un ensemble mathématique, il n'applique ni ne maintient aucun ordre particulier des éléments. Le concept abstrait d'un ensemble n'applique pas l'ordre, donc l'implémentation n'est pas obligée de le faire. Lorsque vous créez un ensemble à partir d'une liste, Python a la liberté de modifier l'ordre des éléments pour les besoins de l'implémentation interne qu'il utilise pour un ensemble, qui est capable d'effectuer des opérations d'ensemble efficacement.
la source
supprimer les doublons et conserver l'ordre par la fonction ci-dessous
vérifier ce lien
la source
En mathématiques, il existe des ensembles et des ensembles ordonnés (osets).
En Python, seuls les ensembles sont directement implémentés. Nous pouvons émuler des osets avec des clés dict régulières ( 3.7+ ).
Donné
Code
Démo
Les répliques sont supprimées, l'ordre d'insertion est conservé.
Opérations de type set sur les clés dict.
Détails
Remarque: une structure non ordonnée n'empêche pas les éléments ordonnés. Au contraire, le maintien de l'ordre n'est pas garanti. Exemple:
On peut être heureux de découvrir qu'une liste et un multiset (mset) sont deux structures de données mathématiques plus fascinantes:
Résumé
* Un multiset peut être indirectement émulé avec
collections.Counter()
, un mappage de type dict de multiplicités (comptes).la source
Comme indiqué dans d'autres réponses, les ensembles sont des structures de données (et des concepts mathématiques) qui ne préservent pas l'ordre des éléments -
Cependant, en utilisant une combinaison d'ensembles et de dictionnaires, il est possible que vous puissiez obtenir ce que vous voulez - essayez d'utiliser ces extraits:
la source
En me basant sur la réponse de Sven, j'ai trouvé en utilisant des collections.OrderedDict m'a aidé à accomplir ce que vous voulez et m'a permis d'ajouter plus d'éléments au dict:
Si vous souhaitez ajouter des éléments tout en les traitant comme un ensemble, vous pouvez simplement faire:
Et vous pouvez effectuer une opération comme z.keys () sur le dict et obtenir l'ensemble:
la source
list(z.keys())
pour obtenir la sortie de la liste.Une implémentation du concept de score le plus élevé ci-dessus qui le ramène à une liste:
Testé (brièvement) sur Python 3.6 et Python 2.7.
la source
Dans le cas où vous avez un petit nombre d'éléments dans vos deux listes initiales sur lesquelles vous souhaitez effectuer une opération de différence de définition, au lieu d'utiliser
collections.OrderedDict
ce qui complique l'implémentation et la rend moins lisible, vous pouvez utiliser:Sa complexité temporelle n'est pas si bonne mais elle est soignée et facile à lire.
la source
Il est intéressant de noter que les gens utilisent toujours le «problème du monde réel» pour plaisanter sur la définition en science théorique.
Si l'ensemble a de l'ordre, vous devez d'abord résoudre les problèmes suivants. Si votre liste contient des éléments en double, quel devrait être l'ordre lorsque vous en faites un ensemble? Quel est l'ordre si nous réunissons deux ensembles? Quel est l'ordre si nous croisons deux ensembles avec un ordre différent sur les mêmes éléments?
De plus, set est beaucoup plus rapide dans la recherche d'une clé particulière, ce qui est très bon pour le fonctionnement des ensembles (et c'est pourquoi vous avez besoin d'un ensemble, mais pas d'une liste).
Si vous vous souciez vraiment de l'index, conservez-le simplement sous forme de liste. Si vous souhaitez toujours effectuer une opération d'ensemble sur les éléments de nombreuses listes, le moyen le plus simple consiste à créer un dictionnaire pour chaque liste avec les mêmes clés dans l'ensemble avec une valeur de liste contenant tous les index de la clé dans la liste d'origine.
la source
Voici un moyen simple de le faire:
la source