162 votes

La conversion d'une liste en un ensemble modifie l'ordre des éléments.

Récemment, j'ai remarqué que lorsque je convertissais un fichier list a set l'ordre des éléments est modifié et est 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 -

  1. Pourquoi cela se produit-il ?
  2. Comment faire des opérations de set (notamment Set Difference) sans perdre l'ordre initial ?

149 votes

@KarlKnechtel - Oui "l'ordre est un concept sans signification pour les ensembles...en mathématiques" mais j'ai des problèmes du monde réel :)

1 votes

Sur CPython 3.6+ unique = list(dict.fromkeys([1, 2, 1]).keys()) . Cela fonctionne parce que dict s préserver l'ordre d'insertion maintenant.

0voto

Po-Yao Niu Points 1

Il est intéressant de constater que les gens utilisent toujours l'expression "problème du monde réel" pour se moquer de la définition de la science théorique.

Si la liste est ordonnée, vous devez d'abord résoudre les problèmes suivants. Si votre liste comporte des éléments en double, quel doit être l'ordre lorsque vous la transformez en ensemble ? Quel est l'ordre si nous unissons deux ensembles ? Quel est l'ordre si nous intersectons 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 bien dans le fonctionnement des sets (et c'est pourquoi vous avez besoin d'un set, mais pas d'une liste).

Si vous tenez vraiment à l'index, gardez-le sous forme de liste. Si vous souhaitez toujours effectuer des opérations sur les éléments de plusieurs listes, la méthode la plus simple consiste à créer un dictionnaire pour chaque liste avec les mêmes clés dans l'ensemble, ainsi qu'une valeur de liste contenant tous les indices de la clé dans la liste originale.

def indx_dic(l):
    dic = {}
    for i in range(len(l)):
        if l[i] in dic:
            dic.get(l[i]).append(i)
        else:
            dic[l[i]] = [i]
    return(dic)

a = [1,2,3,4,5,1,3,2]
set_a  = set(a)
dic_a = indx_dic(a)

print(dic_a)
# {1: [0, 5], 2: [1, 7], 3: [2, 6], 4: [3], 5: [4]}
print(set_a)
# {1, 2, 3, 4, 5}

0voto

silver Points 1

Nous pouvons utiliser collections.Counter pour ça :

# tested on python 3.7
>>> from collections import Counter
>>> lst = ["1", "2", "20", "6", "210"]

>>> for i in Counter(lst):
>>>     print(i, end=" ")
1 2 20 6 210 

>>> for i in set(lst):
>>>     print(i, end=" ")
20 6 2 1 210

0voto

abhay patil Points 29

Vous pouvez supprimer les valeurs dupliquées et conserver l'ordre d'insertion dans la liste, si vous le souhaitez.

lst = [1,2,1,3]
new_lst = []

for num in lst :
    if num not in new_lst :
        new_lst.append(num)

# new_lst = [1,2,3]

n'utilisez pas "sets" pour supprimer les doublons si vous voulez "order",

utiliser des ensembles pour la recherche, par exemple
x dans la liste
prend un temps O(n)

x dans l'ensemble
prend un temps O(1) *dans la plupart des cas

0voto

Azhar hussain Points 61

Réponse tardive mais vous pouvez utiliser Pandas, pd.Series pour convertir une liste tout en préservant l'ordre :

import pandas as pd
x = pd.Series([1, 2, 20, 6, 210, 2, 1])
print(pd.unique(x))

Sortie : array([ 1, 2, 20, 6, 210])

Fonctionne pour une liste de chaînes de caractères

x = pd.Series(['c', 'k', 'q', 'n', 'p','c', 'n'])
print(pd.unique(x))

Sortie ['c' 'k' 'q' 'n' 'p']

-6voto

Aappu Shankar Points 25

Voici un moyen simple de le faire :

x=[1,2,20,6,210]
print sorted(set(x))

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X