Kaip rūšiuoti žodynų sąrašą pagal žodyno vertę „Python“?

Gavau žodynų sąrašą ir noriu, kad kiekvienas elementas būtų suskirstytas pagal konkrečias turto vertes.

Apsvarstykite toliau pateiktą masyvą

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

Kai rūšiuojamas pagal name

 [{'name':'Bart', 'age':10}, {'name':'Homer', 'age':39}] 
1386
16 сент. nustatė masi 16 sep . 2008-09-16 17:27 '08 at 17:27 pm 2008-09-16 17:27
@ 17 atsakymų

Jis gali atrodyti švaresnis naudojant klavišą vietoj cmp:

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

Norėdami išsiaiškinti (kaip nurodyta fitzgeraldsteele komentaruose), pridėkite reverse=True kad surūšiuotumėte pasroviui

1862 m
16 сент. Atsakymas pateikiamas Mario F rugsėjo 16 d 2008-09-16 17:39 '08 at 17:39 pm 2008-09-16 17:39
 import operator 

Jei norite rūšiuoti žodynų sąrašą pagal raktą = 'name':

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

Jei norite rūšiuoti žodynų sąrašą pagal raktą = "amžius":

 list_of_dicts.sort(key=operator.itemgetter('age')) 
113
16 сент. Vemury atsakymas, pateiktas rugsėjo 16 d. 2008-09-16 18:18 '08, 18:18, 2008-09-16 18:18

Jei norite surūšiuoti sąrašą keliais mygtukais, galite atlikti šiuos veiksmus:

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

Tai gana įsilaužėlis, nes jis priklauso nuo verčių konversijos į vieną eilutės vaizdą palyginimui, tačiau jis veikia kaip tikėtasi skaičiams, įskaitant neigiamus (nors jums reikės formatuoti eilutę su nuliais tarpais, jei naudojate numerius)

41
18 мая '10 в 18:28 2010-05-18 18:28 Atsakymą Dologan pateikė gegužės 18 d. 10 val. 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 “ dabar bus tai, ko norite.

(Po 3 metų) Redaguota, kad pridėtumėte:

Naujas key argumentas yra efektyvesnis ir tvarkingesnis. Dabar geriausias atsakymas yra toks:

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

... lambda yra lengviau suprantama kaip IMO, bet YMMV.

29
16 сент. atsakymas pateikiamas pjz rugsėjo 16 d 2008-09-16 17:39 '08 at 17:39 pm 2008-09-16 17:39
 import operator a_list_of_dicts.sort(key=operator.itemgetter('name')) 

„raktas“ naudojamas surūšiuoti pagal savavališką vertę, ir „itemgetter“ nustato šią vertę kiekvieno elemento „vardo“ atributui.

22
16 сент. Atsakymą pateikia efotinis 16 sep . 2008-09-16 17:43 '08 at 17:43 pm 2008-09-16 17:43

Manau, kad jūs reiškėte:

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

Jis bus surūšiuotas taip:

 sorted(l,cmp=lambda x,y: cmp(x['name'],y['name'])) 
16
16 сент. atsakymą pateikė Bartosz Radaczyński 16 sep . 2008-09-16 17:36 '08 at 17:36 pm 2008-09-16 17:36

Perl Schwarz transformacijos naudojimas

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

daryti

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

suteikia

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

Skaityti daugiau apie Schwartz Perl transformaciją

Kompiuterių moksluose „Schwartz“ transformacija yra „Perl“ programavimo idioma, naudojama pagerinti prekių sąrašo rūšiavimą. Ši idioma yra tinkama rūšiavimui pagal palyginimą, kai užsakymas iš tikrųjų yra pagrįstas tam tikro elemento (tam tikro elemento) užsakymu, kai šio turto skaičiavimas yra intensyvi operacija, kuri turėtų būti atliekama minimaliai. „Schwartzy Transform“ skiriasi tuo, kad nenaudoja pavadintų laikinų masyvų.

14
27 мая '13 в 14:21 2013-05-27 14:21 atsakymas pateikiamas gegužės 27 d., 13 val. 14:21 2013-05-27 14:21

Galite naudoti pasirinktinį palyginimo funkciją arba galite perkelti funkciją, kuri apskaičiuoja jūsų pačių rūšiavimo raktą. Tai paprastai yra efektyvesnė, nes raktas skaičiuojamas tik vieną kartą už elementą, o palyginimo funkcija bus vadinama daug kartų.

Tai galite padaryti taip:

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

Tačiau standartinėje bibliotekoje yra bendra procedūra norint gauti savavališkų objektų elementus: itemgetter . Taigi pabandykite:

 from operator import itemgetter x = [{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age':10}] sorted(x, key=itemgetter('name')) 
13
16 сент. Owen atsakymas, pateiktas rugsėjo 16 d. 2008-09-16 17:52 '08 at 17:52 pm 2008-09-16 17:52

Turite įgyvendinti savo palyginimo funkciją, kuri palygins žodynus pagal raktinių žodžių reikšmes. Žr. „ Mini-HOW TO“ rūšiavimas iš „PythonInfo Wiki“

12
16 сент. Matej atsakymas rugsėjo 16 d 2008-09-16 17:31 '08 at 17:31 pm 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 atsakymas pateikiamas forzagreen kovo 17 d. 17 val. 13:29 2017-03-17 13:29

Bandžiau kažką panašaus:

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

Jis dirbo sveikiems skaičiams.

7
14 сент. atsakymą pateikė Sandip Agarwal apie 14 sep. 2012-09-14 11:05 '12, 11:05, 2012-09-14 11:05

Čia yra alternatyvus bendras sprendimas - jis rūšiuoja diktavimo elementus raktais ir vertybėmis. To privalumas yra tas, kad nereikia nurodyti raktų, ir jis vis tiek veiks, jei kai kuriuose žodynuose trūksta kai kurių raktų.

 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 янв. Atsakymas duotas vvladymyrov 22 jan. 2015-01-22 20:21 '15 - 20:21 2015-01-22 20:21

„Panda“ paketo naudojimas yra kitas būdas, nors vykdymo laikas dideliu mastu yra daug lėtesnis nei kitų tradicinių metodų:

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

Toliau pateikiamos kai kurios mažos sąrašo ir didelių (100k +) punktų sąrašo kontrolės vertės:

 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 сент. atsakymas pateikiamas abby sobh 02 sep . 2016-09-02 00:21 '16 at 0:21 2016-09-02 00:21

Kartais, pavyzdžiui, turime naudoti lower()

 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 atsakymas pateikiamas liepos 14 d. 17, 06:21 2017-07-14 06:21

Tarkime, kad turiu žodyną D su toliau pateiktais elementais. Jei norite rūšiuoti, tiesiog naudokite pagrindinį argumentą, kad pasiektumėte pasirinktą funkciją, kaip parodyta žemiau.

 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 апр. atsakymas pateikiamas Shank_Transformer 16 balandžio. 2014-04-16 10:18 '14, 10:18, 2014-04-16 10:18

Čia yra mano atsakymas į atitinkamą klausimą dėl rūšiavimo keliais stulpeliais . Jis taip pat veikia degeneraciniu atveju, kai stulpelių skaičius yra vienas.

2
17 июля '09 в 21:22 2009-07-17 21:22 atsakymas pateikiamas hughdbrown liepos 17 d., 09:21, 2009-07-17 21:22

Jei nereikia originalo listdictionaries , galite jį pakeisti naudodami sort() metodą, naudodami specialią rakto funkciją.

Pagrindinė funkcija:

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

rūšiuoti list :

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

Rūšiuoti pagal vietą:

 data_one.sort(key=get_name) 

Jei jums reikia originalaus list , skambinkite sorted() funkcija, perduodama jį list ir pagrindinei funkcijai, tada priskirkite naują kintamąjį grąžinamam rūšiuojamam list :

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

Spausdinti data_one ir 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 дек. atsakymas duotas 19 dec. 2017-12-19 20:31 '17, 8:31 pm 2017-12-19 20:31