ordenar dicionario pela key

2,020 views
Skip to first unread message

Gustavo Fonseca

unread,
May 20, 2013, 10:13:07 AM5/20/13
to python...@googlegroups.com
bom dia,

sou novo aqui no fórum e na linguagem python. por isso a pergunta amadora.

tenho um dicionario como o exemplo abaixo.

dic  = {'50' : 'xxx', '11' : 'xxx', '1' : 'xxx', '12': 'xxx',  '2': 'xxx'  }

quero ordenar ele pela chave de forma que ele fique assim.

dic  = { '1' : 'xxx',   '2': 'xxx' , '11' : 'xxx' , '12': 'xxx', '50' : 'xxx' }

porem quando eu faço o comando dic.sort()

ele me retorna isso

 dic = { '11' : 'xxx, '12' : 'xxx', '1' : 'xxx',   '2': 'xxx' ,  '50' : 'xxx' }

acho que isso acontece por as chaves estão sendo tratadas como strings e não inteiros.

se alguém souber alguma forma de resolver esse problema posta aí.

desde já agradeço.

Laerte M. Rodrigues

unread,
May 20, 2013, 10:17:10 AM5/20/13
to python...@googlegroups.com
converta suas chaves para números


--
--
------------------------------------
Grupo Python-Brasil
http://www.python.org.br/wiki/AntesDePerguntar
 
<*> Para visitar o site do grupo na web, acesse:
http://groups.google.com/group/python-brasil
 
<*> Para sair deste grupo, envie um e-mail para:
python-brasi...@googlegroups.com
 
---
Você está recebendo esta mensagem porque se inscreveu no grupo "python-brasil" dos Grupos do Google.
Para cancelar a inscrição neste grupo e parar de receber seus e-mails, envie um e-mail para python-brasi...@googlegroups.com.
Para obter mais opções, acesse https://groups.google.com/groups/opt_out.
 
 



--
Grato,

Laerte Mateus Rodrigues
Mestre em Informática -- PUC Minas
Doutorando em Bioinformática -- UFMG

Gustavo Fonseca

unread,
May 20, 2013, 10:20:57 AM5/20/13
to python...@googlegroups.com
Opa laerte,

tem como você postar um exemplo.

Mário Neto

unread,
May 20, 2013, 10:22:36 AM5/20/13
to python...@googlegroups.com
vc pode usar collections mas se vc deixar as chaves como string n vai ter a ordenação que vc deseja:

>>> import collections
>>> dic  = {'50': 'xxx', '11': 'xxx', '1': 'xxx', '12': 'xxx',  '2': 'xxx'}
>>> od = collections.OrderedDict(sorted(dic.items()))
>>> od
OrderedDict([('1', 'xxx'), ('11', 'xxx'), ('12', 'xxx'), ('2', 'xxx'), ('50', 'xxx')])

Se a chave for inteiro terá:

>>> dic  = {50: 'xxx', 11: 'xxx', 1: 'xxx', 12: 'xxx',  2: 'xxx'}
>>> od = collections.OrderedDict(sorted(dic.items()))
>>> od
OrderedDict([(1, 'xxx'), (2, 'xxx'), (11, 'xxx'), (12, 'xxx'), (50, 'xxx')])

Att. Mário Araújo Chaves Neto
Programmer, Designer and U.I. Engineer

MBA in Design Digital - 2008 - FIC
Analysis and Systems Development - 2011 - Estácio
Design and Implementation of Internet Environments - 2003 - FIC

Sandro dos Santos Valentim

unread,
May 20, 2013, 10:23:48 AM5/20/13
to python...@googlegroups.com
dicionario = {'1': None, '2': None, '11': None}
chaves_ordenadas = [int(i) for i in dicionario.keys()]
chaves_ordenadas.sort()
print(chaves_ordenadas)

[1, 2, 11]


Em 20 de maio de 2013 11:13, Gustavo Fonseca <gusta...@gmail.com> escreveu:

Henr"Ikke" Pereira

unread,
May 20, 2013, 10:24:18 AM5/20/13
to python...@googlegroups.com
Em Python, dicionários são não ordenados [1]. Então provavelmente não é isso que você quer fazer.

Copiado da documentação:
>>> a = dict(one=1, two=2, three=3)
>>> b = {'one': 1, 'two': 2, 'three': 3}
>>> c = dict(zip(['one', 'two', 'three'], [1, 2, 3]))
>>> d = dict([('two', 2), ('one', 1), ('three', 3)])
>>> e = dict({'three': 3, 'one': 1, 'two': 2})
>>> a == b == c == d == e
True

Acho que você deve pensar em usar um OrderedDict se precisa de alguma coisa ordenada.[2]





2013/5/20 Gustavo Fonseca <gusta...@gmail.com>



--
Henr"Ikke" G.G. Pereira
+55 (55) 9619-7499
|_|0|_|
|_|_|0|
|0|0|0|

Laerte M. Rodrigues

unread,
May 20, 2013, 10:31:48 AM5/20/13
to python...@googlegroups.com
Gustavo,

nao sei como esta sendo sua entrada de dados, mas ao inserir um novo registro no dicionario, faca a conversao para int

ex:

dic[chave] = valor # Chave eh string

Faça isto

dic[int(chave)] = valor # Chave eh inteiro, ao ordenar, vai ficar do jeito q vc ker

Vinicius Assef

unread,
May 20, 2013, 10:45:20 AM5/20/13
to python...@googlegroups.com
Gustavo, se você é novo em Python e está precisando resolver uma
questão dessa, sugiro você dar uma lida no tutorial de Python [1], que
foi gentilmente traduzido para o Português por alguns colegas daqui da
lista.

Se você não entender como o basicão de Python funciona, talvez você
nem entenda o que te dissermos para fazer.

[1] http://turing.com.br/pydoc/2.7/tutorial/



2013/5/20 Gustavo Fonseca <gusta...@gmail.com>:

Gustavo Fonseca

unread,
May 20, 2013, 10:47:31 AM5/20/13
to python...@googlegroups.com
minha entrada de dados esta sendo de post.

meu codigo é esse
dic = request.POST

o problema é que alem de números tem strings nesse post. 
exemplo:

dic  = {'50': 'xxx', '11': 'xxx', '1': 'xxx', '12': 'xxx',  '2': 'xxx', 'teste': 'teste'}

e quando vou remover o elemento 'teste' da um erro dizendo que o elemento é imutavel 
del dec['teste']

Fábio Cerqueira

unread,
May 20, 2013, 1:37:53 PM5/20/13
to python...@googlegroups.com
Não faz sentido ordenação de um dicionário, a não ser o que é proposto pelo OrderedDict que guarda a ordem que o elementos foram inseridos.

O que você pode fazer é ordenar as keys ao  tentar acessar:



2013/5/20 Gustavo Fonseca <gusta...@gmail.com>



--
Fábio Cerqueira

Joao S. O. Bueno

unread,
May 20, 2013, 1:52:59 PM5/20/13
to Python Brasil
Então Gustavo -
bvom, como o pessoal apontou, se voce tentar fazer isso num dicionário
comum, vai receber um "attribute error" - jṕa que diionários nem tem o
método sort.

Se vocẽ está recebendo os seus dados numa estrutura de mapping, que se
cokmporta como um dicionário e tem também o méotod "sort" é só
providenciar um parâmetro "key" apropriado para a chamada a sort.

Vou demonstrar como seria factivel com um dicionário comum:

>>> ordered_items = [item for item in sorted(dic.items(), key=lambda k: "%010d" % int(k[0]) if k[0].isdigit() else k[0])]>>> print (ordered_items)
[('1', 'xxx'), ('2', 'xxx'), ('11', 'xxx'), ('12', 'xxx'), ('50',
'xxx'), ('estraga_prazeres', 'xxx')]


Então o "key" é uma função que pega a chave do item (k[0]) - se ela
for composta só de digitos, transforma em inteiro, e cria uma string
formatada com 0s prefixados ("11" vira "0000000011", e assim por
diante) - e esse resultado da expressão é o que é usado na ordenação.


Esse resultado não pode ser guardado de volta num dicionário ou a
ordenaão se perde - você ou guarda os items numa lista, ou usa um
collections.ordered_dict e guarda valor por valor lá.

js
-><-

2013/5/20 Gustavo Fonseca <gusta...@gmail.com>:

Marcos Filipe Lino

unread,
May 20, 2013, 10:39:17 AM5/20/13
to python...@googlegroups.com
Gustavo,

Uma alternativa.

dic  = {'50' : 'avx', '11' : 'def', '1' : 'sgr', '12': 'aaa',  '2': 'xbz'  }

chaves = [ int(x) for x in dic.keys() ]
valor = []
for i in chaves:
    valor.append(dic[str(i)])
dic = zip( chaves, valor )
dic.sort()





Atenciosamente,
Marcos Filipe Lino.

Gustavo Fonseca

unread,
May 20, 2013, 2:03:35 PM5/20/13
to python...@googlegroups.com, gwi...@gmail.com
obrigado pelas respostas.

resolvi o problema criando um novo dicionario dessa forma

aa = {}
    for i in range(1,len(dic)-1):
        aa[i] = dic[str(i)]

Juan Lopes

unread,
May 20, 2013, 2:12:07 PM5/20/13
to python...@googlegroups.com
Como assim não faz sentido? Faz sim! Árvores AVL são dicionários
ordenados, assim como árvores rubro-negras e tries. Tem teoria demais
sobre o assunto para simplesmente não fazer sentido.

O único problema é que Python não implementa nada assim na sua
biblioteca padrão, infelizmente.

--
https://github.com/juanplopes

Fábio Cerqueira

unread,
May 21, 2013, 9:48:55 AM5/21/13
to python...@googlegroups.com
Juan,

AVL, não é ordenada, apenas facilita a busca reduzindo a altura da árvore com balanceamento, mas você n está organizando os dados seguindo uma sequência. Dicionários são Hash Map, sendo assim há chaves e valores, então é preciso definir o que você quer ter em ordem, chaves ou valores. 

O mais comum de se encontrar é a necessidade de lembrar a ordem de inserção no hash map.

No PyPi possui várias implementações de outras estruturas de dados, use pip search NOME para encontrá-las.


2013/5/20 Juan Lopes <juanp...@gmail.com>
--
--
------------------------------------
Grupo Python-Brasil
http://www.python.org.br/wiki/AntesDePerguntar

<*> Para visitar o site do grupo na web, acesse:
    http://groups.google.com/group/python-brasil

<*> Para sair deste grupo, envie um e-mail para:
    python-brasi...@googlegroups.com

---
Você está recebendo esta mensagem porque se inscreveu no grupo "python-brasil" dos Grupos do Google.
Para cancelar a inscrição neste grupo e parar de receber seus e-mails, envie um e-mail para python-brasi...@googlegroups.com.
Para obter mais opções, acesse https://groups.google.com/groups/opt_out.





--
Fábio Cerqueira

Juan Lopes

unread,
May 21, 2013, 10:03:35 AM5/21/13
to python...@googlegroups.com
2013/5/21 Fábio Cerqueira <stee...@gmail.com>:
> Juan,
>
> AVL, não é ordenada, apenas facilita a busca reduzindo a altura da árvore
> com balanceamento, mas você n está organizando os dados seguindo uma
> sequência. Dicionários são Hash Map, sendo assim há chaves e valores, então
> é preciso definir o que você quer ter em ordem, chaves ou valores.

AVL é ordenada sim. O percurso in-order numa árvore AVL é o mesmo que
percorrer as chaves em ordem crescente.

Especialmente para RBTrees, as bibliotecas que a implementam até se
aproveitam disso para fazer buscas por lowerBound e upperBound. No map
do C++ [1] (que é implementado com uma RBTree), você tem os métodos
lower_bound e upper_bound. No TreeMap do Java [2], você tem os métodos
headMap e tailMap, que são similares.

[1] http://www.cplusplus.com/reference/map/map/
[2] http://docs.oracle.com/javase/6/docs/api/java/util/TreeMap.html

--
https://github.com/juanplopes

Fábio Cerqueira

unread,
May 21, 2013, 10:58:59 AM5/21/13
to python...@googlegroups.com
Juan,
obrigado pela lembrança/correção sobre a ordenação da AVL no percurso in-order.


2013/5/21 Juan Lopes <juanp...@gmail.com>
--
--
------------------------------------
Grupo Python-Brasil
http://www.python.org.br/wiki/AntesDePerguntar

<*> Para visitar o site do grupo na web, acesse:
    http://groups.google.com/group/python-brasil

<*> Para sair deste grupo, envie um e-mail para:
    python-brasi...@googlegroups.com

---
Você está recebendo esta mensagem porque se inscreveu no grupo "python-brasil" dos Grupos do Google.
Para cancelar a inscrição neste grupo e parar de receber seus e-mails, envie um e-mail para python-brasi...@googlegroups.com.
Para obter mais opções, acesse https://groups.google.com/groups/opt_out.





--
Fábio Cerqueira

Danilo J. S. Bellini

unread,
May 21, 2013, 12:21:50 PM5/21/13
to python-brasil
In [8]: dic  = {'50' : 'xxx', '11' : 'xxx', '1' : 'xxx', '12': 'xxx',  '2': 'xxx'  }

In [9]: from collections import OrderedDict

In [10]: OrderedDict([(k, dic[k]) for k in sorted(dic, key=lambda x: (len(x), x))])
Out[10]: OrderedDict([('1', 'xxx'), ('2', 'xxx'), ('11', 'xxx'), ('12', 'xxx'), ('50', 'xxx')])



Danilo J. S. Bellini
---------------
"It is not our business to set up prohibitions, but to arrive at conventions." (R. Carnap)

Joao S. O. Bueno

unread,
May 21, 2013, 2:03:52 PM5/21/13
to Python Brasil
> key=lambda x: (len(x), x))]

Conte me mais sobre como essa sua função para key funciona quando
um elemento for "10", outro "1234" e outro for "bla", por exemplo. :-)




2013/5/21 Danilo J. S. Bellini <danilo....@gmail.com>:

Danilo J. S. Bellini

unread,
May 21, 2013, 2:20:19 PM5/21/13
to python-brasil
Que legal, isso ordena hexadecimal também...=D
"a", "10", "b7", "fe", "12a"

Embora para hex seria melhor garantir que maiúsculas e minúsculas não se misturarão:
> key=lambda x: (len(x), x.lower()))]

Para o exemplo dado é o suficiente, se ele começar a misturar com outras coisas (o "bla" por exemplo), a situação pode ficar bizarra...=P

Mas se insiste...vamos deixar o Python decidir o que é melhor ao comparar int com string:

def key_func(x):
    try:
        return int(x)
    except ValueError:
        return x

> key = key_func

=)

Reply all
Reply to author
Forward
0 new messages