Recentemente, percebi que, quando estou convertendo um list
emset
a ordem dos elementos é alterado e é classificada pelo personagem.
Considere este exemplo:
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
Minhas perguntas são -
- Por que isso está acontecendo?
- Como posso fazer operações de configuração (especialmente Set Difference) sem perder o pedido inicial?
unique = list(dict.fromkeys([1, 2, 1]).keys())
. Isso funciona porquedict
s preserva o pedido de inserção agora.Respostas:
A
set
é uma estrutura de dados não ordenada, portanto, não preserva a ordem de inserção.Isso depende de seus requisitos. Se você tem uma lista normal e deseja remover algum conjunto de elementos preservando a ordem da lista, você pode fazer isso com uma compreensão de lista:
Se você precisar de uma estrutura de dados que ofereça suporte a testes rápidos de associação e preservação do pedido de inserção , pode usar as chaves de um dicionário Python, que a partir do Python 3.7 preserva o pedido de inserção:
b
não precisa ser pedido aqui - você também pode usar umset
. Observe quea.keys() - b.keys()
retorna a diferença definida como umset
, portanto, não preservará o pedido de inserção.Em versões mais antigas do Python, você pode usar em seu
collections.OrderedDict
lugar:fonte
None
é um singleton garantido por linguagem. Em CPython, o custo real é apenas o ponteiro (embora esse custo esteja sempre lá, mas para um dict, você quase pode considerarNone
e outros singletons ou referências compartilhadas "grátis"), então uma palavra de máquina, provavelmente 8 bytes em computadores modernos . Mas sim, não é tão eficiente em termos de espaço quanto um conjunto poderia ser.dict.fromkeys([1, 2, 1]).keys()
porque os programas regularesdict
preservam a ordem também.No Python 3.6,há outra solução para Python 2 e 3:set()
agora deve manter a ordem, masfonte
x.index
é chamado, é realizada uma busca linear. Se você está bem com a complexidade quadrática, não há razão para usar umset
em primeiro lugar.set()
não está ordenado no Python 3.6, nem mesmo como um detalhe de implementação, você está pensandodict
sint
costumam fazer hash stackoverflow.com/questions/45581901/…x=[1,2,-1,20,6,210]
fazer um conjunto. Você verá que não está ordenado, testado no Python 3.6.Respondendo à sua primeira pergunta, um conjunto é uma estrutura de dados otimizada para operações de conjunto. Como um conjunto matemático, ele não impõe ou mantém nenhuma ordem particular dos elementos. O conceito abstrato de um conjunto não impõe ordem, portanto, a implementação não é necessária. Quando você cria um conjunto a partir de uma lista, Python tem a liberdade de alterar a ordem dos elementos de acordo com as necessidades da implementação interna que usa para um conjunto, que é capaz de realizar operações de conjunto de forma eficiente.
fonte
remova duplicatas e preserve a ordem pela função abaixo
verifique este link
fonte
Em matemática, existem conjuntos e conjuntos ordenados (osets).
Em Python, apenas conjuntos são implementados diretamente. Podemos emular osets com teclas dit regulares ( 3.7+ ).
Dado
Código
Demo
As réplicas são removidas, a ordem de inserção é preservada.
Operações semelhantes a conjuntos em teclas dict.
Detalhes
Nota: uma estrutura não ordenada não exclui elementos ordenados. Em vez disso, a ordem mantida não é garantida. Exemplo:
Pode-se o prazer de descobrir que uma lista e multiset (MSET) são dois, estruturas de dados matemáticos mais fascinantes:
Resumo
* Um multiset pode ser emulado indiretamente com
collections.Counter()
um mapeamento de multiplicidades (contagens) semelhante a um dicionário .fonte
Conforme indicado em outras respostas, conjuntos são estruturas de dados (e conceitos matemáticos) que não preservam a ordem dos elementos -
No entanto, usando uma combinação de conjuntos e dicionários, é possível que você consiga o que deseja - tente usar estes trechos:
fonte
Com base na resposta de Sven, descobri que usar coleções.OrderedDict como me ajudou a realizar o que você deseja e me permite adicionar mais itens ao dict:
Se você deseja adicionar itens, mas ainda tratá-los como um conjunto, basta fazer:
E você pode realizar uma operação como z.keys () no dicionário e obter o conjunto:
fonte
list(z.keys())
para obter a saída da lista.Uma implementação do conceito de pontuação mais alta acima que o traz de volta à lista:
Testado (brevemente) em Python 3.6 e Python 2.7.
fonte
Caso você tenha um pequeno número de elementos em suas duas listas iniciais nas quais deseja fazer a operação de definir diferença, em vez de usar o
collections.OrderedDict
que complica a implementação e a torna menos legível, você pode usar:Sua complexidade de tempo não é tão boa, mas é organizada e fácil de ler.
fonte
É interessante que as pessoas sempre usam 'problema do mundo real' para fazer piada com a definição na ciência teórica.
Se o conjunto estiver em ordem, primeiro você precisa descobrir os seguintes problemas. Se sua lista tiver elementos duplicados, qual deve ser a ordem ao transformá-la em um conjunto? Qual é a ordem se unirmos dois conjuntos? Qual é a ordem se cruzarmos dois conjuntos com ordem diferente nos mesmos elementos?
Além disso, set é muito mais rápido na busca por uma determinada chave, o que é muito bom na operação de conjuntos (e é por isso que você precisa de um conjunto, mas não de uma lista).
Se você realmente se preocupa com o índice, basta mantê-lo como uma lista. Se você ainda deseja fazer a operação de conjunto nos elementos em muitas listas, a maneira mais simples é criar um dicionário para cada lista com as mesmas chaves do conjunto junto com um valor de lista contendo todos os índices da chave na lista original.
fonte
Esta é uma maneira fácil de fazer isso:
fonte