Como você recupera itens de um dicionário na ordem em que são inseridos?

StackOverflow https://stackoverflow.com/questions/60848

  •  09-06-2019
  •  | 
  •  

Pergunta

É possível recuperar itens de um dicionário Python na ordem em que foram inseridos?

Foi útil?

Solução

O Python padrão dict faz isso por padrão se você estiver usando CPython 3.6+ (ou Python 3.7+ para qualquer outra implementação de Python).

Em versões mais antigas do Python você pode usar collections.OrderedDict.

Outras dicas

As outras respostas estão corretas;não é possível, mas você mesmo pode escrever isso.No entanto, caso você não tenha certeza de como realmente implementar algo assim, aqui está uma implementação completa e funcional que dita as subclasses que acabei de escrever e testar.(Observe que a ordem dos valores passados ​​para o construtor é indefinida, mas virá antes dos valores passados ​​posteriormente, e você sempre pode simplesmente não permitir que dictos ordenados sejam inicializados com valores.)

class ordered_dict(dict):
    def __init__(self, *args, **kwargs):
        dict.__init__(self, *args, **kwargs)
        self._order = self.keys()

    def __setitem__(self, key, value):
        dict.__setitem__(self, key, value)
        if key in self._order:
            self._order.remove(key)
        self._order.append(key)

    def __delitem__(self, key):
        dict.__delitem__(self, key)
        self._order.remove(key)

    def order(self):
        return self._order[:]

    def ordered_items(self):
        return [(key,self[key]) for key in self._order]


od = ordered_dict()
od["hello"] = "world"
od["goodbye"] = "cruel world"
print od.order()            # prints ['hello', 'goodbye']

del od["hello"]
od["monty"] = "python"
print od.order()            # prints ['goodbye', 'monty']

od["hello"] = "kitty"
print od.order()            # prints ['goodbye', 'monty', 'hello']

print od.ordered_items()
# prints [('goodbye','cruel world'), ('monty','python'), ('hello','kitty')]

Use OrderedDict(), disponível desde a versão 2.7

Só uma questão de curiosidade:

from collections import OrderedDict
a = {}
b = OrderedDict()
c = OredredDict()

a['key1'] = 'value1'
a['key2'] = 'value2'

b['key1'] = 'value1'
b['key2'] = 'value2'

c['key2'] = 'value2'
c['key1'] = 'value1'

print a == b #True
print a == c #True
print b == c #False

Ou apenas transforme a chave em uma tupla com time.now() como o primeiro campo da tupla.

Então você pode recuperar as chaves com dictname.keys(), sort e pronto!

Gerry

A partir do Python 3.7, o dict padrão preserva a ordem de inserção.De documentos:

Alterado na versão 3.7:A ordem do dicionário é garantidamente uma ordem de inserção.Este comportamento foi um detalhe de implementação do CPython a partir do 3.6.

Então, você deve ser capaz de iterar o dicionário normalmente ou usar popitem().

Você não pode fazer isso com a classe base dict - ela é ordenada por hash.Você poderia construir seu próprio dicionário que é realmente uma lista de pares de chave, valor ou algo assim, que seria ordenado.

Já usei o StableDict antes com bom sucesso.

http://pypi.python.org/pypi/StableDict/0.2

Ou use qualquer uma das implementações para o PEP-372 descrito aqui, como o módulo odict de pythonutils.

Usei com sucesso a implementação do pocoo.org, é tão fácil quanto substituir seu

my_dict={}
my_dict["foo"]="bar"

com

my_dict=odict.odict()
my_dict["foo"]="bar"

e requer apenas este ficheiro

Não é possível, a menos que você armazene as chaves em uma lista separada para referência posterior.

O que você pode fazer é inserir os valores com uma chave que representa a ordem inserida e depois chamar sorted() nos itens.

>>> obj = {}
>>> obj[1] = 'Bob'
>>> obj[2] = 'Sally'
>>> obj[3] = 'Joe'
>>> for k, v in sorted(obj.items()):
...     print v
... 
Bob
Sally
Joe
>>> 

se você não precisa da funcionalidade dict e só precisa retornar as tuplas na ordem em que as inseriu, uma fila não funcionaria melhor?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top