it-swarm-id.com

Bagaimana cara saya mengurutkan daftar kamus berdasarkan nilai kamus?

Saya memiliki daftar kamus dan ingin setiap item diurutkan berdasarkan nilai properti tertentu.

Pertimbangkan array di bawah ini,

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

Ketika diurutkan berdasarkan name, harus menjadi

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

Ini mungkin terlihat lebih bersih menggunakan kunci, bukan cmp:

newlist = sorted(list_to_be_sorted, key=lambda k: k['name']) 

atau seperti yang disarankan J.F.Sebastian dan lainnya,

from operator import itemgetter
newlist = sorted(list_to_be_sorted, key=itemgetter('name')) 

Untuk kelengkapan (seperti yang ditunjukkan dalam komentar oleh fitzgeraldsteele), tambahkan reverse=True untuk mengurutkan menurun

newlist = sorted(l, key=itemgetter('name'), reverse=True)
2038
Mario F
import operator

Untuk mengurutkan daftar kamus dengan kunci = 'nama':

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

Untuk mengurutkan daftar kamus berdasarkan key = 'age':

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

Jika Anda ingin mengurutkan daftar dengan beberapa tombol, Anda dapat melakukan hal berikut:

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']))

Ini agak meretas, karena bergantung pada konversi nilai menjadi representasi string tunggal untuk perbandingan, tetapi berfungsi seperti yang diharapkan untuk angka termasuk yang negatif (meskipun Anda perlu memformat string Anda dengan tepat dengan bantalan nol jika Anda menggunakan angka)

43
Dologan
my_list = [{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}]

my_list.sort(lambda x,y : cmp(x['name'], y['name']))

my_list sekarang akan menjadi apa yang Anda inginkan.

(3 tahun kemudian) Diedit untuk menambahkan:

Argumen key baru lebih efisien dan lebih rapi. Jawaban yang lebih baik sekarang terlihat seperti:

my_list = sorted(my_list, key=lambda k: k['name'])

... lambda adalah, IMO, lebih mudah dipahami daripada operator.itemgetter, tapi YMMV.

38
pjz
import operator
a_list_of_dicts.sort(key=operator.itemgetter('name'))

'key' digunakan untuk mengurutkan berdasarkan nilai sewenang-wenang dan 'itemgetter' menetapkan nilai itu ke atribut 'nama' setiap item.

26
efotinis

Saya kira Anda maksud:

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

Ini akan disortir seperti ini:

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

Menggunakan Schwartzian transform dari Perl,

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

melakukan

sort_on = "name"
decorated = [(dict_[sort_on], dict_) for dict_ in py]
decorated.sort()
result = [dict_ for (key, dict_) in decorated]

memberi

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

Lebih lanjut tentang Transformasi Perl Schwartzian

Dalam ilmu komputer, transformasi Schwartzian adalah pemrograman Perl Idiom digunakan untuk meningkatkan efisiensi penyortiran daftar item. Ini idiom sesuai untuk pengurutan berbasis perbandingan saat pemesanan sebenarnya berdasarkan pemesanan properti tertentu (kunci) dari elemen, di mana menghitung properti itu adalah operasi intensif harus dilakukan beberapa kali minimal. The Schwartzian Transform penting karena tidak menggunakan array sementara bernama.

17
octoback
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']) 
15
forzagreen

Anda bisa menggunakan fungsi perbandingan khusus, atau Anda bisa meneruskan fungsi yang menghitung kunci penyortiran khusus. Itu biasanya lebih efisien karena kuncinya hanya dihitung sekali per item, sedangkan fungsi perbandingan akan dipanggil berkali-kali.

Anda bisa melakukannya dengan cara ini:

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

Tetapi pustaka standar berisi rutin umum untuk mendapatkan item dari objek sewenang-wenang: itemgetter. Jadi coba ini sebagai gantinya:

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

Anda harus mengimplementasikan fungsi perbandingan Anda sendiri yang akan membandingkan kamus dengan nilai kunci nama. Lihat Sortasi Mini-BAGAIMANA dari PythonInfo Wiki

14
Matej

Saya mencoba sesuatu seperti ini:

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

Itu bekerja untuk bilangan bulat juga.

10
Sandip Agarwal

kadang-kadang kita perlu menggunakan lower() misalnya

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}]
9
uingtea

Berikut ini adalah solusi umum alternatif - ini mengurutkan elemen-elemen dict dengan kunci dan nilai-nilai ..__ Keuntungannya - tidak perlu menentukan kunci, dan itu akan tetap berfungsi jika beberapa kunci hilang dalam beberapa kamus.

def sort_key_func(item):
    """ helper function used to sort list of dicts

    :param item: dict
    :return: sorted list of tuples (k, v)
    """
    pairs = []
    for k, v in item.items():
        pairs.append((k, v))
    return sorted(pairs)
sorted(A, key=sort_key_func)
9
vvladymyrov

Menggunakan paket panda adalah metode lain, meskipun runtime dalam skala besar jauh lebih lambat daripada metode yang lebih tradisional yang diusulkan oleh orang lain:

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()

Berikut adalah beberapa nilai patokan untuk daftar kecil dan daftar besar (100k +) daftar berikut:

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
8
abby sobh

Katakanlah saya memiliki Kamus D dengan elemen di bawah ini. Untuk mengurutkan cukup gunakan argumen kunci diurutkan untuk melewati fungsi kustom seperti di bawah ini

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

5

Inilah jawaban saya untuk pertanyaan terkait pengurutan menurut beberapa kolom . Ini juga berfungsi untuk kasus degenerasi di mana jumlah kolom hanya satu.

4
hughdbrown

Jika Anda tidak memerlukan list asli dari dictionaries, Anda dapat memodifikasinya di tempat dengan metode sort() menggunakan fungsi tombol kustom.

Fungsi kunci:

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

    return d["name"]

list yang akan disortir:

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

Mengurutkannya di tempat:

data_one.sort(key=get_name)

Jika Anda memerlukan list asli, panggil fungsi sorted() dengan meneruskannya list dan fungsi kunci, kemudian tetapkan list yang diurutkan yang dikembalikan ke variabel baru:

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

Mencetak data_one dan new_data.

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

Anda dapat menggunakan itemgetter , jika Anda ingin mempertimbangkan kinerjanya. itemgetter biasanya berjalan sedikit lebih cepat dari lambda .

from operator import itemgetter
result = sorted(data, key=itemgetter('age'))  # this will sort list by property order 'age'.
1
vikas0713

Anda dapat menggunakan kode berikut

sorted_dct = sorted(dct_name.items(), key = lambda x : x[1])
0
Loochie