it-swarm-tr.com

Sözlük listesini sözlük değerine göre nasıl sıralarım?

Sözlük listesi var ve her öğenin belirli bir özellik değerine göre sıralanmasını istiyorum.

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

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

name tarafından sıralandığında,

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

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ğerlerinin önerdiği gibi,

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

Bütünlüğü (fitzgeraldsteele tarafından yorumlarda belirtildiği gibi), azalan sıralamak için reverse=True ekleyin

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

Sözlük listesini key = 'name' ile sıralamak için:

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

Sözlük listesini key = 'age' ye göre sıralamak için:

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

Listeyi birden fazla 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']))

Karşılaştırma için değerleri tek bir dize temsili haline dönüştürmeye dayandığı için oldukça zekicedir, ancak negatif olanlar dahil olmak üzere sayılar için beklendiği gibi çalışır (sayıları kullanıyorsanız dizenizi sıfır sıralamayla uygun şekilde biçimlendirmeniz gerekmesine rağmen)

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 şimdi istediğiniz gibi olacak.

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

Yeni key argümanı daha verimli ve düzenli. Şimdi daha iyi bir cevap şuna benziyor:

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

... lambda, IMO, anlaşılması kolay operator.itemgetter, fakat YMMV.

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

'key' keyfi bir değere göre sıralamak için kullanılır ve 'itemgetter' bu değeri her bir maddenin 'name' niteliğine ayarlar.

26
efotinis

Galiba demek istedin:

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

Bu şöyle sıralanır:

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

Perl’den Schwartzian dönüşümünü kullanmak,

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

yap

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

verir

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

Daha fazlası Perl Schwartzian dönüşümü

Bilgisayar bilimlerinde Schwartzian dönüşümü bir Perl programlamadır. deyim, bir öğe listesini sıralama verimliliğini artırmak için kullanılır. Bu deyim, sıralar .__ ise karşılaştırma tabanlı sıralama için uygundur. aslında 'nın belirli bir malının (anahtar) sırasını esas alır. öğeleri, bu özelliği hesaplama yoğun bir işlem olduğu yerlerde. en az sayıda yapılmalıdır. Schwartzian Dönüşüm, adlandırılmış geçici diziler kullanmaması nedeniyle dikkate değerdir.

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

Özel bir karşılaştırma işlevi kullanabilir veya özel bir sıralama anahtarı hesaplayan bir işlevde geçirebilirsiniz. Bu, anahtar, her öğe için yalnızca bir kez hesaplandığından, genellikle daha verimli olurken, karşılaştırma işlevi birçok kez daha çağrılır.

Bu şekilde yapabilirsin:

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

Ancak standart kütüphane, keyfi nesnelerin eşyalarını almak için genel bir rutin içerir: itemgetter. Öyleyse bunun yerine şunu deneyin:

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

Sözlükleri isim tuşlarının değerleri ile karşılaştıracak kendi karşılaştırma fonksiyonunuzu uygulamanız gerekir. Bkz. Mini NASIL TO PythonInfo Wiki ile sıralama

14
Matej

Böyle bir şey denedim:

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

Ayrıca tamsayılar için çalıştı.

10
Sandip Agarwal

örneğin, lower() işlevini kullanmamız gerekiyor.

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

İşte alternatif genel çözüm - anahtar ve değerlere göre dikte unsurlarını sıralar .. __ Bunun avantajı - anahtar belirtmeye gerek yoktur ve bazı anahtarların bazı sözlüklerde eksik olması durumunda yine de işe yarar.

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

Panda paketini kullanmak başka bir yöntemdir, ancak çalışma zamanı büyük ölçüde diğerlerinin önerdiği 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()

İşte küçük bir liste ve büyük bir (100k +) sözlük listesi için bazı referans değerler:

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

Diyelim ki ben aşağıda elemanları olan bir Sözlük D'ye sahibim. Sıralamak için sadece aşağıdaki gibi özel işlevi geçmek için sıralı olarak 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

5

Burada benim birden fazla sütuna göre sıralama ile ilgili soruya cevabım . Ayrıca sütun sayısının sadece bir olduğu dejenere durum için de geçerlidir.

4
hughdbrown

list dosyasının orijinal dictionaries'sine ihtiyacınız yoksa, özel bir anahtar işlevi kullanarak sort() yöntemiyle yerinde değiştirebilirsiniz.

Anahtar işlevi:

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

    return d["name"]

Sıralanacak list:

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

Yerinde sıralama:

data_one.sort(key=get_name)

Orijinal list dosyasına ihtiyacınız varsa, list ve key işlevini geçen sorted() işlevini çağırın, sonra döndürülen sıralanmış list işlevini 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)

data_one ve new_data yazdırma.

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

Performansı değerlendirmek istiyorsanız, itemgetter komutunu kullanabilirsiniz. itemgetter tipik olarak lambda öğesinden biraz daha hızlı çalışır.

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

Aşağıdaki kodu kullanabilirsiniz

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