Qual seria uma boa maneira de passar de {2:3, 1:89, 4:5, 3:0}
para {1:89, 2:3, 3:0, 4:5}
?
Eu verifiquei algumas postagens, mas todas elas usam o operador "classificado" que retorna tuplas.
Qual seria uma boa maneira de passar de {2:3, 1:89, 4:5, 3:0}
para {1:89, 2:3, 3:0, 4:5}
?
Eu verifiquei algumas postagens, mas todas elas usam o operador "classificado" que retorna tuplas.
Respostas:
Os dicionários Python padrão não são ordenados. Mesmo se você classificasse os pares (chave, valor), não seria possível armazená-los de dict
uma maneira que preservasse a ordem.
A maneira mais fácil é usar OrderedDict
, que lembra a ordem na qual os elementos foram inseridos:
In [1]: import collections
In [2]: d = {2:3, 1:89, 4:5, 3:0}
In [3]: od = collections.OrderedDict(sorted(d.items()))
In [4]: od
Out[4]: OrderedDict([(1, 89), (2, 3), (3, 0), (4, 5)])
Não importa o modo como od
está impresso; funcionará como esperado:
In [11]: od[1]
Out[11]: 89
In [12]: od[3]
Out[12]: 0
In [13]: for k, v in od.iteritems(): print k, v
....:
1 89
2 3
3 0
4 5
Para usuários do Python 3, é necessário usar o em .items()
vez de .iteritems()
:
In [13]: for k, v in od.items(): print(k, v)
....:
1 89
2 3
3 0
4 5
sorted_dict = dict(sorted(unsorted_dict.items()))
Os próprios dicionários não possuem itens solicitados como tal, caso você queira imprimi-los etc. em alguma ordem, aqui estão alguns exemplos:
No Python 2.4 e acima:
mydict = {'carl':40,
'alan':2,
'bob':1,
'danny':3}
for key in sorted(mydict):
print "%s: %s" % (key, mydict[key])
dá:
alan: 2
bob: 1
carl: 40
danny: 3
(Python abaixo de 2,4 :)
keylist = mydict.keys()
keylist.sort()
for key in keylist:
print "%s: %s" % (key, mydict[key])
Fonte: http://www.saltycrane.com/blog/2007/09/how-to-sort-python-dictionary-by-keys/
for key, value in sorted(mydict.items())"
Na documentação da collections
biblioteca do Python :
>>> from collections import OrderedDict
>>> # regular unsorted dictionary
>>> d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}
>>> # dictionary sorted by key -- OrderedDict(sorted(d.items()) also works
>>> OrderedDict(sorted(d.items(), key=lambda t: t[0]))
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])
>>> # dictionary sorted by value
>>> OrderedDict(sorted(d.items(), key=lambda t: t[1]))
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])
>>> # dictionary sorted by length of the key string
>>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0])))
OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)])
reverse=True
por exemplo OrderedDict(sorted(d.items(), reverse=True, key=lambda t: t[0]))
Unexpected type(s): (List[str]) Possible types: (Mapping) (Iterable[Tuple[Any, Any]])
Para o CPython / PyPy 3.6 e qualquer Python 3.7 ou superior, isso é feito facilmente com:
>>> d = {2:3, 1:89, 4:5, 3:0}
>>> dict(sorted(d.items()))
{1: 89, 2: 3, 3: 0, 4: 5}
{key:d[key] for key in sorted(d.keys())}
Existem vários módulos Python que fornecem implementações de dicionário que mantêm automaticamente as chaves na ordem de classificação. Considere o módulo de contêineres classificados , que é uma implementação pura em Python e rápida como C. Há também uma comparação de desempenho com outras opções populares comparadas entre si.
Usar um ditado ordenado é uma solução inadequada se você precisar adicionar e remover constantemente pares de chave / valor enquanto também itera.
>>> from sortedcontainers import SortedDict
>>> d = {2:3, 1:89, 4:5, 3:0}
>>> s = SortedDict(d)
>>> s.items()
[(1, 89), (2, 3), (3, 0), (4, 5)]
O tipo SortedDict também suporta pesquisas e exclusão de locais indexados, o que não é possível com o tipo de dict interno.
>>> s.iloc[-1]
4
>>> del s.iloc[2]
>>> s.keys()
SortedSet([1, 2, 4])
Simplesmente:
d = {2:3, 1:89, 4:5, 3:0}
sd = sorted(d.items())
for k,v in sd:
print k, v
Resultado:
1 89
2 3
3 0
4 5
sd
é uma lista de tuplas, não um dicionário. (embora ainda útil.)
Como outros mencionaram, os dicionários são inerentemente desordenados. No entanto, se o problema estiver apenas exibindo dicionários de maneira ordenada, você poderá substituir o __str__
método em uma subclasse de dicionário e usar essa classe de dicionário em vez do incorporado dict
. Por exemplo.
class SortedDisplayDict(dict):
def __str__(self):
return "{" + ", ".join("%r: %r" % (key, self[key]) for key in sorted(self)) + "}"
>>> d = SortedDisplayDict({2:3, 1:89, 4:5, 3:0})
>>> d
{1: 89, 2: 3, 3: 0, 4: 5}
Observe que isso não muda nada sobre como as chaves são armazenadas, a ordem em que elas voltarão quando você iterar sobre elas, etc., exatamente como elas são exibidas print
no console do python ou no console.
Encontrou outra maneira:
import json
print json.dumps(d, sort_keys = True)
upd:
1. isso também classifica objetos aninhados (obrigado @DanielF).
2. Os dicionários python não são ordenados, portanto, é possível imprimir ou atribuir apenas a str.
No Python 3.
>>> D1 = {2:3, 1:89, 4:5, 3:0}
>>> for key in sorted(D1):
print (key, D1[key])
dá
1 89
2 3
3 0
4 5
O dicionário Python não era ordenado antes do Python 3.6. Na implementação do Python 3.6 do CPython, o dicionário mantém a ordem de inserção. A partir do Python 3.7, isso se tornará um recurso de linguagem.
No log de alterações do Python 3.6 ( https://docs.python.org/3.6/whatsnew/3.6.html#whatsnew36-compactdict ):
O aspecto de preservação de pedidos dessa nova implementação é considerado um detalhe da implementação e não deve ser considerado (isso pode mudar no futuro, mas é desejável que essa nova implementação de ditado no idioma seja liberada algumas vezes antes de alterar as especificações do idioma. para exigir a semântica de preservação de pedidos para todas as implementações atuais e futuras do Python, isso também ajuda a preservar a compatibilidade com versões anteriores da linguagem em que a ordem de iteração aleatória ainda está em vigor, por exemplo, Python 3.5).
No documento do Python 3.7 ( https://docs.python.org/3.7/tutorial/datastructures.html#dictionaries ):
A execução da lista (d) em um dicionário retorna uma lista de todas as chaves usadas no dicionário, em ordem de inserção (se você deseja que seja classificada, basta usar a classificação (d)).
Portanto, diferente das versões anteriores, você pode classificar um ditado após o Python 3.6 / 3.7. Se você deseja classificar um dict aninhado, incluindo o subdict dentro, é possível:
test_dict = {'a': 1, 'c': 3, 'b': {'b2': 2, 'b1': 1}}
def dict_reorder(item):
return {k: sort_dict(v) if isinstance(v, dict) else v for k, v in sorted(item.items())}
reordered_dict = dict_reorder(test_dict)
https://gist.github.com/ligyxy/f60f0374defc383aa098d44cfbd318eb
Aqui encontrei uma solução mais simples para classificar o ditado python por chave usando pprint
. por exemplo.
>>> x = {'a': 10, 'cd': 20, 'b': 30, 'az': 99}
>>> print x
{'a': 10, 'b': 30, 'az': 99, 'cd': 20}
mas enquanto estiver usando o pprint, ele retornará o ditado classificado
>>> import pprint
>>> pprint.pprint(x)
{'a': 10, 'az': 99, 'b': 30, 'cd': 20}
Existe uma maneira fácil de classificar um dicionário.
De acordo com sua pergunta,
A solução é :
c={2:3, 1:89, 4:5, 3:0}
y=sorted(c.items())
print y
(Onde c, é o nome do seu dicionário.)
Este programa fornece a seguinte saída:
[(1, 89), (2, 3), (3, 0), (4, 5)]
como você queria.
Outro exemplo é:
d={"John":36,"Lucy":24,"Albert":32,"Peter":18,"Bill":41}
x=sorted(d.keys())
print x
Dá a saída:['Albert', 'Bill', 'John', 'Lucy', 'Peter']
y=sorted(d.values())
print y
Dá a saída:[18, 24, 32, 36, 41]
z=sorted(d.items())
print z
Dá a saída:
[('Albert', 32), ('Bill', 41), ('John', 36), ('Lucy', 24), ('Peter', 18)]
Por isso, alterando-o em chaves, valores e itens, você pode imprimir como o que você queria.
Gerará exatamente o que você deseja:
D1 = {2:3, 1:89, 4:5, 3:0}
sort_dic = {}
for i in sorted(D1):
sort_dic.update({i:D1[i]})
print sort_dic
{1: 89, 2: 3, 3: 0, 4: 5}
Mas essa não é a maneira correta de fazer isso, porque, poderia mostrar um comportamento distinto com diferentes dicionários, que aprendi recentemente. Por isso, Tim sugeriu o caminho perfeito na resposta da minha consulta que estou compartilhando aqui.
from collections import OrderedDict
sorted_dict = OrderedDict(sorted(D1.items(), key=lambda t: t[0]))
Acho que a coisa mais fácil é classificar o ditado por chave e salvar a chave classificada: par de valores em um novo ditado.
dict1 = {'renault': 3, 'ford':4, 'volvo': 1, 'toyota': 2}
dict2 = {} # create an empty dict to store the sorted values
for key in sorted(dict1.keys()):
if not key in dict2: # Depending on the goal, this line may not be neccessary
dict2[key] = dict1[key]
Para tornar mais claro:
dict1 = {'renault': 3, 'ford':4, 'volvo': 1, 'toyota': 2}
dict2 = {} # create an empty dict to store the sorted values
for key in sorted(dict1.keys()):
if not key in dict2: # Depending on the goal, this line may not be neccessary
value = dict1[key]
dict2[key] = value
Você pode criar um novo dicionário, classificando o dicionário atual por chave, conforme sua pergunta.
Este é o seu dicionário
d = {2:3, 1:89, 4:5, 3:0}
Crie um novo dicionário d1 classificando este d usando a função lambda
d1 = dict(sorted(d.items(), key = lambda x:x[0]))
d1 deve ser {1: 89, 2: 3, 3: 0, 4: 5}, classificado com base nas chaves em d.
Os dictos Python não são ordenados. Normalmente, isso não é um problema, pois o caso de uso mais comum é fazer uma pesquisa.
A maneira mais simples de fazer o que você deseja seria criar uma collections.OrderedDict
inserção dos elementos na ordem de classificação.
ordered_dict = collections.OrderedDict([(k, d[k]) for k in sorted(d.keys())])
Se você precisar iterar, como sugeriram outros acima, a maneira mais simples seria iterar sobre as chaves classificadas. Exemplos-
Imprimir valores classificados por chaves:
# create the dict
d = {k1:v1, k2:v2,...}
# iterate by keys in sorted order
for k in sorted(d.keys()):
value = d[k]
# do something with k, value like print
print k, value
Obter lista de valores classificados por chaves:
values = [d[k] for k in sorted(d.keys())]
for k,value in sorted(d.items()):
é melhor: evita acessar o ditado por chave novamente no loop
Eu venho com uma classificação de ditado de linha única.
>> a = {2:3, 1:89, 4:5, 3:0}
>> c = {i:a[i] for i in sorted(a.keys())}
>> print(c)
{1: 89, 2: 3, 3: 0, 4: 5}
[Finished in 0.4s]
Espero que isso seja útil.
Esta função classifica qualquer dicionário recursivamente por sua chave. Ou seja, se algum valor no dicionário também for um dicionário, ele também será classificado por sua chave. Se você estiver executando no CPython 3.6 ou superior, é possível fazer uma simples alteração para usar um em dict
vez de um OrderedDict
.
from collections import OrderedDict
def sort_dict(d):
items = [[k, v] for k, v in sorted(d.items(), key=lambda x: x[0])]
for item in items:
if isinstance(item[1], dict):
item[1] = sort_dict(item[1])
return OrderedDict(items)
#return dict(items)
Gente, você está complicando as coisas ... é bem simples
from pprint import pprint
Dict={'B':1,'A':2,'C':3}
pprint(Dict)
A saída é:
{'A':2,'B':1,'C':3}
A solução mais simples é que você deve obter uma lista da ordem de classificação do dict e depois iterar sobre o dict. Por exemplo
a1 = {'a':1, 'b':13, 'd':4, 'c':2, 'e':30}
a1_sorted_keys = sorted(a1, key=a1.get, reverse=True)
for r in a1_sorted_keys:
print r, a1[r]
A seguir, será apresentada a saída (ordem de pedido)
e 30
b 13
d 4
c 2
a 1
Uma comparação de tempo dos dois métodos no 2.7 mostra que eles são praticamente idênticos:
>>> setup_string = "a = sorted(dict({2:3, 1:89, 4:5, 3:0}).items())"
>>> timeit.timeit(stmt="[(k, val) for k, val in a]", setup=setup_string, number=10000)
0.003599141953657181
>>> setup_string = "from collections import OrderedDict\n"
>>> setup_string += "a = OrderedDict({1:89, 2:3, 3:0, 4:5})\n"
>>> setup_string += "b = a.items()"
>>> timeit.timeit(stmt="[(k, val) for k, val in b]", setup=setup_string, number=10000)
0.003581275490432745
from operator import itemgetter
# if you would like to play with multiple dictionaries then here you go:
# Three dictionaries that are composed of first name and last name.
user = [
{'fname': 'Mo', 'lname': 'Mahjoub'},
{'fname': 'Abdo', 'lname': 'Al-hebashi'},
{'fname': 'Ali', 'lname': 'Muhammad'}
]
# This loop will sort by the first and the last names.
# notice that in a dictionary order doesn't matter. So it could put the first name first or the last name first.
for k in sorted (user, key=itemgetter ('fname', 'lname')):
print (k)
# This one will sort by the first name only.
for x in sorted (user, key=itemgetter ('fname')):
print (x)
dictionary = {1:[2],2:[],5:[4,5],4:[5],3:[1]}
temp=sorted(dictionary)
sorted_dict = dict([(k,dictionary[k]) for i,k in enumerate(temp)])
sorted_dict:
{1: [2], 2: [], 3: [1], 4: [5], 5: [4, 5]}
Ou use pandas
,
Demo:
>>> d={'B':1,'A':2,'C':3}
>>> df=pd.DataFrame(d,index=[0]).sort_index(axis=1)
A B C
0 2 1 3
>>> df.to_dict('int')[0]
{'A': 2, 'B': 1, 'C': 3}
>>>
Vejo:
Minha sugestão é essa, pois permite que você ordene um ditado ou mantenha um ditado classificado enquanto adiciona itens e pode precisar adicionar itens no futuro:
Construa a dict
partir do zero à medida que avança. Tenha uma segunda estrutura de dados, uma lista, com sua lista de chaves. O pacote bisect possui uma função de classificação, que permite inserir em uma lista classificada ou classificar sua lista após preencher completamente seu ditado. Agora, quando você itera sobre seu ditado, em vez disso, itera sobre a lista para acessar cada chave de maneira ordenada, sem se preocupar com a representação da estrutura do dict (que não foi feita para classificação).
l = dict.keys()
l2 = l
l2.append(0)
l3 = []
for repeater in range(0, len(l)):
smallnum = float("inf")
for listitem in l2:
if listitem < smallnum:
smallnum = listitem
l2.remove(smallnum)
l3.append(smallnum)
l3.remove(0)
l = l3
for listitem in l:
print(listitem)