Kako razvrstati popis rječnika prema rječničkoj vrijednosti u Pythonu?

Dobio sam popis rječnika i želim da svaki element bude razvrstan prema određenim vrijednostima svojstava.

Razmotrite niz u nastavku,

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

Kada sortiranje po name treba

 [{'name':'Bart', 'age':10}, {'name':'Homer', 'age':39}] 
1386
16 сент. postavlja masi na 16 sep . 2008-09-16 17:27 '08 u 17:27 2008-09-16 17:27
@ 17 odgovora

Može izgledati čišći pomoću ključa umjesto cmp-a:

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

Za potpunost (kao što je navedeno u komentarima fitzgeraldsteele), dodajte reverse=True da biste razvrstali nizvodno

1862
16 сент. Odgovor je dan Mario F 16. rujna 2008-09-16 17:39 '08 u 17:39 2008-09-16 17:39
 import operator 

Da biste razvrstali popis rječnika prema ključu = 'ime':

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

Da biste razvrstali popis rječnika prema ključu = "dob":

 list_of_dicts.sort(key=operator.itemgetter('age')) 
113
16 сент. Odgovor koji je dao vemury 16. rujna. 2008-09-16 18:18 '08 u 18:18 2008-09-16 18:18

Ako popis želite razvrstati po nekoliko tipki, možete učiniti sljedeće:

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

To je prilično haker jer se za usporedbu oslanja na konverziju vrijednosti u prikaz jednog niza, ali radi prema očekivanjima za brojeve, uključujući i one negativne (iako ćete morati formatirati niz s nula razmaknica na odgovarajući način ako koristite brojeve)

41
18 мая '10 в 18:28 2010-05-18 18:28 Odgovor daje Dologan 18. svibnja 2010. u 18:28 2010-05-18 18:28
 my_list = [{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}] my_list.sort(lambda x,y : cmp(x['name'], y['name'])) 

my_list će sada biti ono što želite.

(3 godine kasnije) Uređeno za dodavanje:

Novi key argument je učinkovitiji i uredniji. Sada je najbolji odgovor sljedeći:

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

... lambda je, IMO, lakše razumjeti nego operator.itemgetter , ali YMMV.

29
16 сент. odgovor je dan pjz 16. \ t 2008-09-16 17:39 '08 u 17:39 2008-09-16 17:39
 import operator a_list_of_dicts.sort(key=operator.itemgetter('name')) 

"key" se koristi za sortiranje po proizvoljnoj vrijednosti, a "itemgetter" postavlja ovu vrijednost za atribut "name" svakog elementa.

22
16 сент. Odgovor daje efotinis na 16 sep . 2008-09-16 17:43 '08 u 17:43 2008-09-16 17:43

Mislim da ste mislili:

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

Razvrstat će se na sljedeći način:

 sorted(l,cmp=lambda x,y: cmp(x['name'],y['name'])) 
16
16 сент. odgovor daje Bartosz Radaczyński 16 sep . 2008-09-16 17:36 '08 u 17:36 2008-09-16 17:36

Koristeći Perl Schwarz transformaciju,

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

učiniti

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

to daje

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

Pročitajte više o Schwartz Perl transformaciji

U računalnoj znanosti, Schwartzova transformacija je Perl programski idiom koji se koristi za poboljšanje sortiranja popisa stavki. Ovaj idiom je prikladan za sortiranje na temelju usporedbe, kada je naručivanje zapravo utemeljeno na naručivanju određenog svojstva (ključa) elemenata, pri čemu je izračun tog svojstva intenzivan rad koji bi se trebao obaviti minimalno. Schwartzy Transform se razlikuje po tome što ne koristi imenovane privremene nizove.

14
27 мая '13 в 14:21 2013-05-27 14:21 odgovor je dat oktoback 27. svibnja '13 u 14:21 2013-05-27 14:21

Možete koristiti funkciju prilagođene usporedbe ili možete prenijeti funkciju koja izračunava vlastiti ključ za sortiranje. To je obično učinkovitije jer se ključ izračunava samo jednom po stavci, dok će funkcija usporedbe biti pozvana još mnogo puta.

To možete učiniti na sljedeći način:

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

No standardna knjižnica sadrži opći postupak za dobivanje elemenata proizvoljnih objekata: itemgetter . Pokušajte sljedeće:

 from operator import itemgetter x = [{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age':10}] sorted(x, key=itemgetter('name')) 
13
16 сент. Odgovor koji je dao Owen 16. rujna. 2008-09-16 17:52 '08 u 17:52 2008-09-16 17:52

Morate implementirati svoju vlastitu funkciju usporedbe, koja će uspoređivati ​​rječnike prema vrijednostima imena ključa. Vidi Razvrstavanje Mini-HOW TO s PythonInfo Wiki

12
16 сент. Odgovor dao Matej 16. rujna 2008-09-16 17:31 '08 u 17:31 2008-09-16 17:31
 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']) 
11
17 марта '17 в 13:29 2017-03-17 13:29 odgovor je dat forzagreen 17. ožujka u 13:29 2017-03-17 13:29

Pokušao sam nešto ovako:

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

To je radio za integers.

7
14 сент. odgovor je dao Sandip Agarwal na 14 sep. 2012-09-14 11:05 '12 u 11:05 2012-09-14 11:05

Ovdje je alternativno opće rješenje - sortira elemente dikta pomoću tipki i vrijednosti. Prednost ovoga je u tome što nema potrebe za navođenjem ključeva i to će i dalje raditi ako neki ključevi nedostaju u nekim rječnicima.

 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) 
6
22 янв. Odgovor se daje vvladymyrov 22 jan. 2015-01-22 20:21 '15 u 20:21 2015-01-22 20:21

Korištenje paketa pandas je još jedna metoda, iako je vrijeme izvršavanja na velikoj skali puno sporiji od tradicionalnijih metoda koje nude drugi:

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

U nastavku su navedene neke kontrolne vrijednosti za maleni popis i veliki (100 k +) popis diktata:

 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 
5
02 сент. odgovor je dan abby sobh 02 sep . 2016-09-02 00:21 '16 u 0:21 2016-09-02 00:21

Ponekad trebamo koristiti lower() , na primjer

 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}] 
4
14 июля '17 в 6:21 2017-07-14 06:21 odgovor je dat uingtea 14. srpnja '17 u 6:21 2017-07-14 06:21

Recimo da imam rječnik D s elementima ispod. Da biste sortirali, jednostavno upotrijebite argument ključa u sortiranju da biste proslijedili prilagođenu funkciju, kao što je prikazano ispod.

 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
16 апр. odgovor je dan Shank_Transformer 16 apr. 2014-04-16 10:18 '14 u 10:18 2014-04-16 10:18

Ovdje je moj odgovor na odgovarajuće pitanje o razvrstavanju po nekoliko stupaca . Također radi za degenerirani slučaj u kojem je broj stupaca jedan.

2
17 июля '09 в 21:22 2009-07-17 21:22 odgovor se daje hughdbrown 17. srpnja u 21:22 2009-07-17 21:22

Ako izvorni list ne trebate iz dictionaries , možete ga promijeniti pomoću metode sort() koristeći funkciju posebnog ključa.

Ključna funkcija:

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

list za sortiranje:

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

Poredaj po mjestu:

 data_one.sort(key=get_name) 

Ako vam je potreban izvorni list , nazovite funkciju sorted() , proslijedite joj list i funkciju ključa, a zatim vratite sortiranu list novu varijablu:

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

Ispišite data_one i data_one .

 >>> print(data_one) [{'name': 'Bart', 'age': 10}, {'name': 'Homer', 'age': 39}] >>> print(new_data) [{'name': 'Bart', 'age': 10}, {'name': 'Homer', 'age': 39}] 
0
19 дек. odgovor je dan srig 19 dec. 2017-12-19 20:31 '17 u 20:31 2017-12-19 20:31