it-swarm.com.de

Wie sortiere ich eine Liste von Wörterbüchern nach einem Wert des Wörterbuchs?

Ich habe eine Liste von Wörterbüchern und möchte, dass jedes Element nach bestimmten Eigenschaftswerten sortiert wird.

Berücksichtigen Sie das Array unten,

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

Wenn nach name sortiert, sollte es werden

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

Es kann sauberer aussehen, wenn ein Schlüssel anstelle eines cmp verwendet wird:

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

oder wie von J.F.Sebastian und anderen vorgeschlagen,

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

Der Vollständigkeit halber (wie in Kommentaren von fitzgeraldsteele angegeben), fügen Sie reverse=True hinzu, um absteigend zu sortieren

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

So sortieren Sie die Liste der Wörterbücher nach Schlüssel = "Name":

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

So sortieren Sie die Liste der Wörterbücher nach Schlüssel = "Alter":

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

Wenn Sie die Liste nach mehreren Schlüsseln sortieren möchten, können Sie Folgendes tun:

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

Es ist ziemlich hackhaft, da es zum Vergleich auf der Umwandlung der Werte in eine einzelne Zeichenfolgendarstellung beruht. Es funktioniert jedoch wie erwartet für Zahlen einschließlich negativer (obwohl Sie Ihre Zeichenfolge mit Nullen auffüllen müssen, wenn Sie Zahlen verwenden)

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 ist jetzt das, was Sie wollen.

(3 Jahre später) Bearbeitet:

Das neue Argument key ist effizienter und übersichtlicher. Eine bessere Antwort sieht jetzt so aus:

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

... das Lambda ist IMO einfacher zu verstehen als operator.itemgetter, aber YMMV.

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

'key' wird verwendet, um nach einem beliebigen Wert zu sortieren, und 'itemgetter' setzt diesen Wert auf das 'name'-Attribut jedes Elements.

26
efotinis

Ich denke du hast gemeint:

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

Das wäre so sortiert:

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

Schwartzian-Transformation von Perl verwenden,

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

tun

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

gibt

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

Mehr zu Perl-Schwartzian-Transformation

In der Informatik ist die Schwartzsche Transformation eine Perl-Programmierung Idiom zur Verbesserung der Effizienz beim Sortieren einer Liste von Elementen. Diese idiom ist für die vergleichsbasierte Sortierung geeignet, wenn die Reihenfolge .__ ist. tatsächlich basierend auf der Bestellung einer bestimmten Eigenschaft (des Schlüssels) der Elemente, bei denen das Berechnen dieser Eigenschaft eine intensive Operation ist, die sollte minimal durchgeführt werden. Der Schwartzianer Transformation ist bemerkenswert, da benannte temporäre Arrays nicht verwendet werden.

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

Sie können eine benutzerdefinierte Vergleichsfunktion verwenden oder eine Funktion übergeben, die einen benutzerdefinierten Sortierschlüssel berechnet. Dies ist normalerweise effizienter, da der Schlüssel nur einmal pro Element berechnet wird, während die Vergleichsfunktion viel öfter aufgerufen wird.

Sie könnten es so machen:

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

Die Standardbibliothek enthält jedoch eine generische Routine zum Abrufen beliebiger Objekte: itemgetter. Also versuche es stattdessen:

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

Sie müssen eine eigene Vergleichsfunktion implementieren, die die Wörterbücher anhand der Werte der Namenstasten vergleicht. Siehe Sortieren von Mini-HOW TO aus dem PythonInfo-Wiki

14
Matej

Ich habe so etwas ausprobiert:

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

Es funktionierte auch für ganze Zahlen.

10
Sandip Agarwal

irgendwann müssen wir beispielsweise lower() verwenden

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

Hier ist die alternative allgemeine Lösung - es sortiert Elemente von dict nach Schlüsseln und Werten. Der Vorteil davon - keine Notwendigkeit, Schlüssel anzugeben, und es würde trotzdem funktionieren, wenn einige Schlüssel in einigen Wörterbüchern fehlen.

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

Die Verwendung des Pandapakets ist eine andere Methode, obwohl die Laufzeit im großen Maßstab viel langsamer ist als die von anderen vorgeschlagenen traditionellen Methoden:

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

Hier sind einige Benchmark-Werte für eine kleine Liste und eine große (100.000 +) Liste von Diagrammen:

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

Nehmen wir an, ich habe ein Wörterbuch D mit Elementen unten. Um zu sortieren, verwenden Sie einfach das Schlüsselargument sortiert, um die benutzerdefinierten Funktionen wie folgt zu übergeben

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

Hier ist meine Antwort auf eine verwandte Frage zum Sortieren nach mehreren Spalten . Es funktioniert auch für den degenerierten Fall, bei dem die Anzahl der Spalten nur eine ist.

4
hughdbrown

Wenn Sie die ursprüngliche list von dictionaries nicht benötigen, können Sie sie mit der sort()-Methode direkt mit einer benutzerdefinierten Tastenfunktion ändern.

Schlüsselfunktion:

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

    return d["name"]

Die list muss sortiert werden:

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

Sortieren vor Ort:

data_one.sort(key=get_name)

Wenn Sie die ursprüngliche list benötigen, rufen Sie die sorted()-Funktion auf, übergeben Sie die list- und die key-Funktion, und weisen Sie die zurückgegebene sortierte list einer neuen Variablen zu:

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

data_one und new_data drucken.

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

Sie können itemgetter verwenden, wenn Sie die Leistung berücksichtigen möchten. itemgetter läuft normalerweise etwas schneller als lambda .

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

Sie können den folgenden Code verwenden

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