Frage

Ich habe eine Liste von Wörterbüchern und wollen jedes Element durch eine bestimmte Eigenschaft Werte sortiert werden.

Berücksichtigen Sie das Array unten,

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

Wenn von name sortiert, sollte sich

[{'name':'Bart', 'age':10}, {'name':'Homer', 'age':39}]
War es hilfreich?

Lösung

Es sauberer aussehen kann einen Schlüssel stattdessen eine cmp mit:

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

oder als J.F.Sebastian und andere vorgeschlagen,

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

Für die Vollständigkeit (wie in den Kommentaren von fitzgeraldsteele wies darauf hin), fügt reverse=True absteigend zu sortieren

newlist = sorted(l, key=itemgetter('name'), reverse=True)

Andere Tipps

import operator

Um die Liste der Wörter key = 'name' zu sortieren:

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

die Liste der Wörter key = 'Alter' zu sortieren:

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

Wenn Sie die Liste durch mehrere Schlüssel sortieren 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 vielmehr hackish, da sie die Werte, auf die Umwandlung in einen einzigen String-Darstellung für den Vergleich beruht, aber es funktioniert wie für Zahlen einschließlich negative erwartet (obwohl Sie die Zeichenfolge entsprechend mit Null Polsterungen formatiert werden müssen, wenn Sie mit Zahlen)

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

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

my_list wird nun sein, was Sie wollen.

(3 Jahre später) Edited hinzufügen:

Das neue key Argument ist effizienter und übersichtlicher. Eine bessere Antwort nun wie folgt aussieht:

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

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

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

‚Schlüssel‘ verwendet wird, um einen beliebigen Wert zu sortieren und ‚itemgetter‘ setzt diesen Wert auf jedes Stück ‚name‘ Attribut.

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

Ich denke, Sie haben gemeint:

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

Das ist wie diese sortiert werden würde:

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

Unter Verwendung Schwartzian Transformation von Perl,

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]

gibt

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

Mehr Perl Schwartzian verwandeln

  

In der Informatik, verwandelt der Schwartzian ist eine Perl-Programmierung   Idiom verwendet, um die Effizienz der Sortierung eine Liste der Elemente zu verbessern. Diese   Idiom ist geeignet zum Vergleich basierte Sortier wenn die Ordnung ist   tatsächlich auf der Grundlage der Bestellung einer bestimmten Eigenschaft (der Schlüssel) der   Elemente, in denen diese Eigenschaft ist eine intensive Rechenoperation, dass   sollte eine minimale Anzahl von Malen durchgeführt werden. die Schwartzian   Verwandeln Sie zeichnet sich dadurch aus, dass es nicht nur vorübergehend Arrays namens nicht verwendet.

Sie können eine eigene Vergleichsfunktion verwenden, oder Sie könnten in einer Funktion übergeben, die einen benutzerdefinierten Sortierschlüssel berechnet. Das ist in der Regel effizienter, da der Schlüssel nur einmal pro Artikel berechnet wird, während die Vergleichsfunktion noch viele Male aufgerufen werden würde.

Sie können es auf diese Weise tun:

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

Aber die Standard-Bibliothek enthält eine generische Routine für Gegenstände beliebiger Objekte erhalten: itemgetter. So versuchen, diese stattdessen:

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

Sie haben eine eigene Vergleichsfunktion zu implementieren, die die Worte Werte von Namenstasten vergleichen werden. Siehe Sortierung Mini-HOW TO aus PythonInfo Wiki

Hier ist die Alternative allgemeine Lösung - es sortiert Elemente von dict von Schlüsseln und Werten. Der Vorteil davon -. Keine Notwendigkeit, Schlüssel angeben, und es würde immer noch funktionieren, wenn einige Schlüssel in einigen Worten 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)

irgendwann müssen wir lower() zum Beispiel 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}]

habe ich versucht, so etwas wie folgt aus:

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

Es funktioniert für ganze Zahlen als auch.

, um die Pandas Paket zu verwenden ist eine andere Methode, obwohl es Laufzeit in großem Maßstab ist viel langsamer als die traditionellen Methoden von anderen vorgeschlagen:

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 Eckwerte für eine kleine Liste und eine große (100k +) Liste des dicts:

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

Nehmen wir an ich ein Wörterbuch D H'V unten mit Elementen. Um Art nur in sortierter Schlüsselargument verwenden, um benutzerdefinierte Funktion übergeben, wie unten

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

Hier ist meine Antwort auf eine ähnliche Frage auf die Sortierung nach mehrere Spalten . Es funktioniert auch für den degenerierten Fall, in dem die Anzahl der Spalten ist nur ein.

Wenn Sie nicht die ursprüngliche list von dictionaries benötigen, können Sie es an Ort und Stelle mit sort() Methode mit einer benutzerdefinierten Schlüsselfunktion ändern können.

Key-Funktion:

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

    return d["name"]

Die list sortiert werden:

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

Sortieranlagen es an Ort und Stelle:

data_one.sort(key=get_name)

Wenn Sie den ursprünglichen list benötigen, rufen Sie die Funktion sorted() den list und die Tastenfunktion vorbei, dann weisen Sie die zurück sortierte list eine neue Variablen:

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

Druck data_one und new_data.

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

Sie können verwenden itemgetter , wenn Sie die Leistung zu betrachten. itemgetter der Regel läuft etwas schneller als Lambda .

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

Sie können den folgenden Code verwenden

sorted_dct = sorted(dct_name.items(), key = lambda x : x[1])
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top