valor - transformar lista em dicionario python




Como faço para classificar uma lista de dicionários por um valor do dicionário? (12)

às vezes precisamos usar lower() por exemplo

lists = [{'name':'Homer', 'age':39},
  {'name':'Bart', 'age':10},
  {'name':'abby', 'age':9}]

lists = sorted(lists, key=lambda k: k['name'])
print(lists)
# [{'name':'Bart', 'age':10}, {'name':'Homer', 'age':39}, {'name':'abby', 'age':9}]

lists = sorted(lists, key=lambda k: k['name'].lower())
print(lists)
# [ {'name':'abby', 'age':9}, {'name':'Bart', 'age':10}, {'name':'Homer', 'age':39}]

Eu tenho uma lista de dicionários e quero que cada item seja classificado por valores de propriedade específicos.

Leve em consideração o array abaixo,

[{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}]

Quando classificado por name , deve se tornar

[{'name':'Bart', 'age':10}, {'name':'Homer', 'age':39}]


Eu acho que você quis dizer:

[{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}]

Isso seria classificado assim:

sorted(l,cmp=lambda x,y: cmp(x['name'],y['name']))

Eu tentei algo assim:

my_list.sort(key=lambda x: x['name'])

Funcionou para números inteiros também.


Se você não precisa da list original de dictionaries , você pode modificá-la no local com o método sort() usando uma função de chave personalizada.

Função chave:

def get_name(d):
    """ Return the value of a key in a dictionary. """

    return d["name"]

A list a ser classificada:

data_one = [{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age': 10}]

Classificando-o no local:

data_one.sort(key=get_name)

Se você precisar da list original, chame a função sorted() passando a list e a função de chave, em seguida, atribua a list classificada retornada a uma nova variável:

data_two = [{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age': 10}]
new_data = sorted(data_two, key=get_name)

Imprimindo data_one e data_one .

>>> print(data_one)
[{'name': 'Bart', 'age': 10}, {'name': 'Homer', 'age': 39}]
>>> print(new_data)
[{'name': 'Bart', 'age': 10}, {'name': 'Homer', 'age': 39}]

Se você quiser classificar a lista por várias chaves, poderá fazer o seguinte:

my_list = [{'name':'Homer', 'age':39}, {'name':'Milhouse', 'age':10}, {'name':'Bart', 'age':10} ]
sortedlist = sorted(my_list , key=lambda elem: "%02d %s" % (elem['age'], elem['name']))

É bastante hackish, pois depende da conversão dos valores em uma única representação de string para comparação, mas funciona como esperado para números que incluem números negativos (embora você precise formatar sua string apropriadamente com zero preenchimentos se estiver usando números)


Usar o pacote pandas é outro método, embora seu tempo de execução em larga escala seja muito mais lento do que os métodos mais tradicionais propostos por outros:

import pandas as pd

listOfDicts = [{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}]
df = pd.DataFrame(listOfDicts)
df = df.sort_values('name')
sorted_listOfDicts = df.T.to_dict().values()

Aqui estão alguns valores de referência para uma lista pequena e uma lista grande (100k +) de ditos:

setup_large = "listOfDicts = [];\
[listOfDicts.extend(({'name':'Homer', 'age':39}, {'name':'Bart', 'age':10})) for _ in range(50000)];\
from operator import itemgetter;import pandas as pd;\
df = pd.DataFrame(listOfDicts);"

setup_small = "listOfDicts = [];\
listOfDicts.extend(({'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}));\
from operator import itemgetter;import pandas as pd;\
df = pd.DataFrame(listOfDicts);"

method1 = "newlist = sorted(listOfDicts, key=lambda k: k['name'])"
method2 = "newlist = sorted(listOfDicts, key=itemgetter('name')) "
method3 = "df = df.sort_values('name');\
sorted_listOfDicts = df.T.to_dict().values()"

import timeit
t = timeit.Timer(method1, setup_small)
print('Small Method LC: ' + str(t.timeit(100)))
t = timeit.Timer(method2, setup_small)
print('Small Method LC2: ' + str(t.timeit(100)))
t = timeit.Timer(method3, setup_small)
print('Small Method Pandas: ' + str(t.timeit(100)))

t = timeit.Timer(method1, setup_large)
print('Large Method LC: ' + str(t.timeit(100)))
t = timeit.Timer(method2, setup_large)
print('Large Method LC2: ' + str(t.timeit(100)))
t = timeit.Timer(method3, setup_large)
print('Large Method Pandas: ' + str(t.timeit(1)))

#Small Method LC: 0.000163078308105
#Small Method LC2: 0.000134944915771
#Small Method Pandas: 0.0712950229645
#Large Method LC: 0.0321750640869
#Large Method LC2: 0.0206089019775
#Large Method Pandas: 5.81405615807

Vamos dizer que eu tenho um dicionário D com elementos abaixo. Para classificar apenas use o argumento-chave em classificado para passar a função personalizada como abaixo

D = {'eggs': 3, 'ham': 1, 'spam': 2}

def get_count(tuple):
    return tuple[1]

sorted(D.items(), key = get_count, reverse=True)
or
sorted(D.items(), key = lambda x: x[1], reverse=True)  avoiding get_count function call

https://wiki.python.org/moin/HowTo/Sorting/#Key_Functions


Você pode usar uma função de comparação personalizada ou pode passar uma função que calcule uma chave de classificação personalizada. Isso geralmente é mais eficiente, pois a chave é calculada apenas uma vez por item, enquanto a função de comparação seria chamada muito mais vezes.

Você poderia fazer assim:

def mykey(adict): return adict['name']
x = [{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age':10}]
sorted(x, key=mykey)

Mas a biblioteca padrão contém uma rotina genérica para obter itens de objetos arbitrários: itemgetter . Então tente isso:

from operator import itemgetter
x = [{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age':10}]
sorted(x, key=itemgetter('name'))


import operator

Para classificar a lista de dicionários por key = 'name':

list_of_dicts.sort(key=operator.itemgetter('name'))

Para ordenar a lista de dicionários por key = 'age':

list_of_dicts.sort(key=operator.itemgetter('age'))

a = [{'name':'Homer', 'age':39}, ...]

# This changes the list a
a.sort(key=lambda k : k['name'])

# This returns a new list (a is not modified)
sorted(a, key=lambda k : k['name']) 




data-structures