Dicionário Python: as chaves () e os valores () sempre estão na mesma ordem?


312

Parece que as listas retornadas keys()e os values()métodos de um dicionário são sempre um mapeamento 1 para 1 (assumindo que o dicionário não seja alterado entre chamar os 2 métodos).

Por exemplo:

>>> d = {'one':1, 'two': 2, 'three': 3}
>>> k, v = d.keys(), d.values()
>>> for i in range(len(k)):
    print d[k[i]] == v[i]

True
True
True

Se você não alterar o dicionário entre chamadas keys()e chamadas values(), é errado assumir que o loop for acima sempre imprimirá True? Não encontrei nenhuma documentação confirmando isso.


1
No CPython 3.7 (e superior, presumivelmente), você pode confiar na ordem de iteração de uma ordem de inserção de dicionário correspondente. mail.python.org/pipermail/python-dev/2017-December/151283.html
BallpointBen

O @BallpointBen está no CPython 3.6 e posterior e em todas as outras implementações em Python começando com Python 3.7
Boris

Respostas:


353

Encontrou isto:

Se items(), keys(), values(), iteritems(), iterkeys(), e itervalues()são chamados sem modificações intervenientes para o dicionário, as listas corresponderá diretamente.

Na documentação 2.x e documentação 3.x .


5
aparentemente a declaração na documentação 3.x é mais clara: "a ordem dos itens corresponderá diretamente"
Shaohua Li

4
Este texto está ausente na documentação 3.7. Só posso supor que é porque "Dict mantém a ordem de inserção" em 3.7: mail.python.org/pipermail/python-dev/2017-December/151283.html
EliadL

80

Sim, o que você observou é realmente uma propriedade garantida - chaves (), valores () e itens () retornam listas em ordem congruente, se o ditado não for alterado. iterkeys () & c também iteram na mesma ordem que as listas correspondentes.


1
No entanto, caso a lista seja alterada, o Pandas dataframeoferece uma alternativa em que os itens podem ser atualizados ou excluídos, e a ordem e os locais de índice dos itens em uma estrutura semelhante a um ditado permanecem fixos.
Ville

48

Sim, é garantido no python 2.x :

Se as visualizações de chaves, valores e itens forem iteradas sem modificações no dicionário, a ordem dos itens corresponderá diretamente.



6

Boas referências aos documentos. Veja como você pode garantir o pedido, independentemente da documentação / implementação:

k, v = zip(*d.iteritems())

1
No python3.x, use dict.items ()
Good Will


4

Pelo que vale a pena, algum código de produção usado pesado que eu escrevi é baseado nessa suposição e nunca tive problemas com isso. Eu sei que isso não é verdade :-)

Se você não quiser correr o risco, eu usaria iteritems (), se puder.

for key, value in myDictionary.iteritems():
    print key, value

-2

Não fiquei satisfeito com essas respostas, pois queria garantir que os valores exportados tivessem a mesma ordem, mesmo ao usar ditados diferentes.

Aqui você especifica a ordem das chaves antecipadamente, os valores retornados sempre terão a mesma ordem, mesmo que o ditado mude, ou use um ditado diferente.

keys = dict1.keys()
ordered_keys1 = [dict1[cur_key] for cur_key in keys]
ordered_keys2 = [dict2[cur_key] for cur_key in keys]
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.