Dict sortieren nach...

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
ich1988

hallo!
hab ein dict mit werten wie {"wort_als_string":"anzahl_des_worter_als_string").
nun wäre es toll, wenn das dict nach der anzahl der wörter sortiert würde; also nach inhalt des feldes nr2...
danke für Eure hilfe
henning
User
Beiträge: 274
Registriert: Dienstag 26. Juli 2005, 18:37

Du kannst ein dict nicht sortieren, weil es intern als Hash gespeichert wird (google wird dir da helfen).
Stell es dir wie eine Mathematische Menge vor: Es gibt nirgends iInformationen über die Reihenfolge.

Du kannst aber z.B. eine Liste aus allesn Schlüsseln machen und diese sortieren:

Code: Alles auswählen

sorted_keys = sorted(mein_dict.keys())
for k in sorted keys:
  print "Wort:", k, "Anzahl:", mein_dict[k]
helmut
User
Beiträge: 57
Registriert: Mittwoch 2. November 2005, 07:45
Wohnort: Dormagen

Hallo Gast,

die Ausgabe, sortiert nach den dict-Werten, ist so möglich:

Code: Alles auswählen

zahlen = {'1':'eins',
               '2':'zwei',
               '3':'drei',
               '4':'vier',
               '5':'fuenf'}

#Schluessel und Werte vertauschen
r_zahlen={}
for k in zahlen.keys():
    r_zahlen[zahlen[k]]=k

v_list = zahlen.values()
v_list.sort()

#Ausgabe der Werte, sortiert in alphabetischer Reihenfolge der Werte
for v in v_list:
    print r_zahlen[v], v
Gruss Helmut

Edit (Leonidas): Code in Python-Tags gesetzt.
Ronnie
User
Beiträge: 73
Registriert: Sonntag 21. März 2004, 17:44

Eine Liste von Tuplen wäre vieleicht hilfreicher als ein Dictionary:

Code: Alles auswählen

counted = { 'red': 12, 'green': 9, 'blue': 17 }

def by_count (a, b):
	if counted[a] < counted[b]:
		return -1
	elif counted[a] == counted[b]:
		return 0
	else:
		return 1

L = counted.keys
L.sort(cmp=by_count)

ordered = [(k, counted[k]) for k in L ]
Edit (Leonidas): Code in Python-Tags gesetzt.
Ronnie
User
Beiträge: 73
Registriert: Sonntag 21. März 2004, 17:44

Oder nochmal etwas schöner:

Code: Alles auswählen

counted = { 'red': 12, 'green': 9, 'blue': 17 }
L = counted.items()

def by_second(j):
	return j[1]

L.sort(key=by_second)
BlackJack

helmut hat geschrieben:

Code: Alles auswählen

#Schluessel und Werte vertauschen
r_zahlen={}
for k in zahlen.keys():
    r_zahlen[zahlen[k]]=k
Das funktioniert aber nur wenn die Werte auch alle eindeutig sind. ich1988 hatte im Beispiel aber ein Dictionary mit Worten und Anzahlen. Der Satz "Python ist cool" würde dann zu:

Code: Alles auswählen

histogram = { 'Python': 1, 'cool': 1, 'ist': 1 }
Das Dictionary lässt sich schlecht umdrehen.

Zu Ronnies Lösung: `by_second` kann man durch `operator.itemgetter(1)` ersetzen.
sea-live
User
Beiträge: 440
Registriert: Montag 18. Februar 2008, 12:24
Wohnort: RP

mit python 2.5
gehts auch so

Code: Alles auswählen

def main():
    data = [{'Volume': '1285500', 'Adj Close': '9.84', 'High': '10.18', 'Low': '9.70', 'Date': '2008-04-25', 'Close': '9.84', 'Open': '9.74'},
    {'Volume': '1121700', 'Adj Close': '9.67', 'High': '9.70', 'Low': '9.36', 'Date': '2008-04-24', 'Close': '9.67', 'Open': '9.45'},
    {'Volume': '1513700', 'Adj Close': '9.41', 'High': '9.45', 'Low': '8.95', 'Date': '2008-04-23', 'Close': '9.41', 'Open': '8.98'},
    {'Volume': '601800', 'Adj Close': '9.03', 'High': '9.09', 'Low': '8.87', 'Date': '2008-04-22', 'Close': '9.03', 'Open': '8.90'},
    {'Volume': '481100', 'Adj Close': '8.87', 'High': '8.99', 'Low': '8.82', 'Date': '2008-04-21', 'Close': '8.87', 'Open': '8.95'},
    {'Volume': '672800', 'Adj Close': '8.82', 'High': '8.94', 'Low': '8.65', 'Date': '2008-04-17', 'Close': '8.82', 'Open': '8.89'},
    {'Volume': '485000', 'Adj Close': '8.89', 'High': '8.94', 'Low': '8.78', 'Date': '2008-04-18', 'Close': '8.89', 'Open': '8.90'},
    {'Volume': '753300', 'Adj Close': '8.81', 'High': '8.81', 'Low': '8.51', 'Date': '2008-04-16', 'Close': '8.81', 'Open': '8.63'}]

    sortiert_daten = sorted(data, key=lambda x: x['Date'])   
    print 'Ergebniss'
    print sortiert_daten
   
main()
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Dir ist schon klar, von wann der Thread ist, oder :-) ? Außerdem würde man statt deinem Lambda-Ausdruck 'operator.itemgetter("Date")' verwenden.
ne0h
User
Beiträge: 115
Registriert: Samstag 16. Februar 2008, 11:35

2 1/2 Jahre später... ?

LOL :lol:


ne0h
sea-live
User
Beiträge: 440
Registriert: Montag 18. Februar 2008, 12:24
Wohnort: RP

ich war auf der suche nach einer lösung und binn auf diesen tread gestossen

da ich eine lösung für dict listen habe habe ich sie hier reingestellt

gibts nen besseren thread in sachen dict sort

die suche lieferte nur den hier

wo muss das hier 'operator.itemgetter("Date")' hin
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Code: Alles auswählen

import operator
data.sort(key=operator.itemgetter("Date"))
sea-live
User
Beiträge: 440
Registriert: Montag 18. Februar 2008, 12:24
Wohnort: RP

EyDu hat geschrieben:

Code: Alles auswählen

import operator
data.sort(key=operator.itemgetter("Date"))
wo liegt der vorteil wenn ich dazu ein modul brauche
desweiteren

keine funktion
mit deinem code
meiner ausgeklammert funzt

Code: Alles auswählen

import operator
def main():
    data = [{'Volume': '1285500', 'Adj Close': '9.84', 'High': '10.18', 'Low': '9.70', 'Date': '2008-04-25', 'Close': '9.84', 'Open': '9.74'},
    {'Volume': '1121700', 'Adj Close': '9.67', 'High': '9.70', 'Low': '9.36', 'Date': '2008-04-24', 'Close': '9.67', 'Open': '9.45'},
    {'Volume': '1513700', 'Adj Close': '9.41', 'High': '9.45', 'Low': '8.95', 'Date': '2008-04-23', 'Close': '9.41', 'Open': '8.98'},
    {'Volume': '601800', 'Adj Close': '9.03', 'High': '9.09', 'Low': '8.87', 'Date': '2008-04-22', 'Close': '9.03', 'Open': '8.90'},
    {'Volume': '481100', 'Adj Close': '8.87', 'High': '8.99', 'Low': '8.82', 'Date': '2008-04-21', 'Close': '8.87', 'Open': '8.95'},
    {'Volume': '672800', 'Adj Close': '8.82', 'High': '8.94', 'Low': '8.65', 'Date': '2008-04-17', 'Close': '8.82', 'Open': '8.89'},
    {'Volume': '485000', 'Adj Close': '8.89', 'High': '8.94', 'Low': '8.78', 'Date': '2008-04-18', 'Close': '8.89', 'Open': '8.90'},
    {'Volume': '753300', 'Adj Close': '8.81', 'High': '8.81', 'Low': '8.51', 'Date': '2008-04-16', 'Close': '8.81', 'Open': '8.63'}]

    #sortiert_daten = sorted(data, key=lambda x: x['Date'])   
    sortiert_daten = data.sort(key=operator.itemgetter("Date"))
    print 'Ergebniss'
    print sortiert_daten
   
main()
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

sea-live hat geschrieben:keine funktion
mit deinem code
meiner ausgeklammert funzt
`sort` sortiert ja auch *IN PLACE*. Folglich wird `data` direkt verändert und es wird `None` zurückgegeben. Du müsstest also ``print data`` machen oder ``sortiert_daten = sorted(data, key=operator.itemgetter("Date"))``

Edit: Vergessene Klammer hinzugefügt.
Zuletzt geändert von Trundle am Montag 28. April 2008, 21:09, insgesamt 1-mal geändert.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

sea-live hat geschrieben:wo liegt der vorteil wenn ich dazu ein modul brauche
Weil die Funktionalität von itemgetter dokumentiert ist und man nicht überlegen muss was irgendwelche Funktionen machen. Außerdem ist er womöglich auch schneller.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

sea-live hat geschrieben:wo liegt der vorteil wenn ich dazu ein modul brauche
desweiteren
Es ist einfach gut getesteter Code aus der Standardbibliothek und warum sollte man etwas neu schreiben, was es schon gibt und genau dazu gedacht ist. Außerdem verringert es die eigenen Fehler. Und natülrich ist es auch viel lesbarer als ein lambda-Ausdruck.
sea-live
User
Beiträge: 440
Registriert: Montag 18. Februar 2008, 12:24
Wohnort: RP

Leonidas hat geschrieben:
sea-live hat geschrieben:wo liegt der vorteil wenn ich dazu ein modul brauche
Weil die Funktionalität von itemgetter dokumentiert ist und man nicht überlegen muss was irgendwelche Funktionen machen. Außerdem ist er womöglich auch schneller.
überzeugend und einleuchtend Danke für die Überaus lehrreiche Info
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

EyDu hat geschrieben:
sea-live hat geschrieben:wo liegt der vorteil wenn ich dazu ein modul brauche
desweiteren
Es ist einfach gut getesteter Code aus der Standardbibliothek und warum sollte man etwas neu schreiben, was es schon gibt und genau dazu gedacht ist. Außerdem verringert es die eigenen Fehler. Und natülrich ist es auch viel lesbarer als ein lambda-Ausdruck.
Das sehe ich anders. Ja, das Ding ist dazu gedacht. Aber ich kann nicht erkennen, was an ``lambda x: x["Date"]`` unlesbar ist, zumal man mit "itemgetter" auch nichts anfangen kann, wenn man nicht weiß was es genau tut.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Zugegeben, der Lambda-Ausdruck ist nicht schwierig zu lesen, aber man muss relativ genau hinschauen. "itemgetter" hingegen ist, zumindest für mich, sehr intuitiv. Und die Standard-Bibliothek nicht zu kennen, sollte ja wohl keine ausrede sein.
sea-live
User
Beiträge: 440
Registriert: Montag 18. Februar 2008, 12:24
Wohnort: RP

Mag sein das wir das hier jetzt breittreten
aber ich finde in keiner docu was zu itemgetter
weder bei google nioch bei pydocu und schon garnicht in wx docu

kann mal jemand diesen ominösen docu link hier einstellen

dazu ist das forum doch da es gibt massig was zu lamda

beides funktioniert wie man an den beispielen sieht

mich stört halt nur das lamda bereits ab 2.4 für diese dinge optimiert wurde
und in den standart namensraum übernommmen wurde
ich soll nun fürs bessere verständniss eine bibliotek nachladen was
beim compalieren dann zusätzlichen platz beansprucht.
Diskusion erwünscht minimalismuss gefordert beim Programmieren!
Antworten