Python'daki sözlüğün değerine göre sözlüklerin bir listesini nasıl sıralayabilirim?

sözlüklerin bir listesini aldım ve her öğenin belirli bir özellik değerlerine göre sıralanmasını istiyorum.

aşağıdaki diziyi göz önünde bulundurun,

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

name ile sıralandığında

olmalıdır
[{'name':'Bart', 'age':10}, {'name':'Homer', 'age':39}]
1397
tarihinde sordu masi 2008-09-16 18:27:47
kaynak

17 ответов

bir cmp yerine bir anahtar kullanarak daha temiz görünebilir:

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

veya J. F. Sebastian ve diğerleri,

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

tamlık için (fitzgeraldsteele tarafından yorumlarda belirtildiği gibi), reverse=True

sıralamak için reverse=True ekleyin
newlist = sorted(l, key=itemgetter('name'), reverse=True)
1873
cevap Mario F 2014-12-31 22:39:49
kaynak
import operator

sözlüklerin listesini anahtar = 'name' ile sıralamak için:

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

='age':

anahtarına göre sözlüklerin listesini sıralamak için
list_of_dicts.sort(key=operator.itemgetter('age'))
114
cevap cedbeu 2013-05-01 18:42:05
kaynak

listeyi birden çok tuşa göre sıralamak istiyorsanız aşağıdakileri yapabilirsiniz:

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

değerleri karşılaştırma için tek bir dize gösterimine dönüştürmeye dayandığı için oldukça zayıftır, ancak negatif olanlar da dahil olmak üzere sayılar için beklendiği gibi çalışır (dizenizi, sayıları kullanıyorsanız sıfır dolgu ile uygun bir şekilde biçimlendirmeniz gerekecektir)

42
cevap Dologan 2013-04-10 15:31:15
kaynak
my_list = [{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}]

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

my_list şimdi ne istediğinizi olacak.

(3 yıl sonra) eklemek için düzenlenmiş:

yeni key argümanı daha verimli ve daha düzgün. Daha iyi bir cevap şu şekilde görünüyor:

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

...lambda, IMO, operator.itemgetter den daha kolay anlaşılır, ancak YMMV'DİR.

30
cevap pjz 2016-06-06 16:42:15
kaynak
import operator
a_list_of_dicts.sort(key=operator.itemgetter('name'))

'anahtar' keyfi bir değere göre sıralamak için kullanılır ve' ıtemgetter 'her öğenin' ad ' özniteliğine bu değeri ayarlar.

23
cevap efotinis 2008-09-16 18:43:51
kaynak

sanırım demek istediniz:

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

bu şöyle sıralanır:

sorted(l,cmp=lambda x,y: cmp(x['name'],y['name']))
17
cevap Bartosz Radaczyński 2008-09-16 18:36:54
kaynak

Schwartzian kullanarak Perl dönüşümü,

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

do

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

-

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

daha 'Schwartzian transform

bilgisayar bilimi, Schwartzian dönüşümü bir Perl programlama deyim öğelerin bir listesini sıralama verimliliğini artırmak için kullanılır. Bunca deyim karşılaştırma tabanlı sıralama için uygun olduğunda sipariş aslında belirli bir özelliğin (anahtar) siparişine dayanarak öğeleri, bu özellik bilgisayar yoğun bir işlemdir en az sayıda kez yapılmalıdır. Bu Schwartzian Transform, adlandırılmış geçici diziler kullanmaması açısından dikkat çekicidir.

15
cevap octoback 2013-05-27 15:21:03
kaynak

özel bir karşılaştırma işlevi kullanabilirsiniz veya özel bir sıralama anahtarını hesaplayan bir işleve geçebilirsiniz. Karşılaştırma işlevi çok daha fazla kez çağrılırken, anahtar yalnızca öğe başına bir kez hesaplanırken genellikle daha verimli olur.

bunu şu şekilde yapabilirsiniz:

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

ancak standart kitaplık, rasgele nesnelerin öğelerini almak için genel bir rutin içerir: itemgetter . Bunun yerine bunu deneyin:

from operator import itemgetter
x = [{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age':10}]
sorted(x, key=itemgetter('name'))
14
cevap Owen 2008-09-16 18:52:14
kaynak

sözlükleri isim anahtarlarının değerleriyle karşılaştıracak kendi karşılaştırma işlevinizi uygulamanız gerekir. Bkz. Sorting Mini-Pythonİnfo Wiki

13
cevap Matej 2008-09-16 18:31:52
kaynak
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']) 
12
cevap forzagreen 2017-03-17 13:29:50
kaynak

böyle bir şey denedim:

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

tamsayılar için de çalıştı.

8
cevap Sandip Agarwal 2013-04-10 15:30:29
kaynak

işte alternatif genel çözüm-dict öğelerini anahtar ve değerlere göre sıralar. Bunun avantajı-anahtarları belirtmenize gerek yok ve bazı anahtarların bazı sözlüklerde eksik olması durumunda hala çalışacaktır.

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)
7
cevap vvladymyrov 2015-01-22 20:21:17
kaynak

pandalar paketini kullanarak başka bir yöntemdir, ancak büyük ölçekli çalışma zamanı başkaları tarafından önerilen daha geleneksel yöntemlerden çok daha yavaştır:

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

burada küçük bir liste ve büyük (100k+) dicts listesi için bazı kriter değerleri vardır:

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
6
cevap abby sobh 2016-11-09 19:58:57
kaynak

bazen lower() örneğin

kullanmanız gerekir
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}]
5
cevap uingtea 2017-07-14 06:21:08
kaynak

, aşağıdaki öğelerle bir sözlük D H'v diyelim. Sıralamak için, özel işlevi

gibi geçmek için sıralanmış anahtar argümanını kullanın
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

3
cevap SuaveShank 2014-04-16 11:35:10
kaynak

İşte birden çok sütun sıralama ile ilgili bir soruya cevabım. Ayrıca, sütun sayısının yalnızca bir olduğu dejenere durum için de çalışır.

2
cevap hughdbrown 2017-05-23 15:34:51
kaynak

dictionaries orijinal list gerekiyorsa, özel bir anahtar işlevini kullanarak sort() yöntemi ile yerinde değiştirebilirsiniz.

anahtar işlevi:

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

    return d["name"]

list sıralanacak:

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

yerinde sıralama:

data_one.sort(key=get_name)

orijinal list gerekiyorsa, sorted() işlevini list ve anahtar işlevi, daha sonra list ile döndürülen değeri yeni bir değişkene atayın:

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

baskı data_one ve new_data .

>>> print(data_one)
[{'name': 'Bart', 'age': 10}, {'name': 'Homer', 'age': 39}]
>>> print(new_data)
[{'name': 'Bart', 'age': 10}, {'name': 'Homer', 'age': 39}]
0
cevap srig 2017-12-19 20:31:30
kaynak