Seite 1 von 2

Dict sortieren nach...

Verfasst: Sonntag 11. Dezember 2005, 01:21
von 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

Verfasst: Sonntag 11. Dezember 2005, 09:34
von henning
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]

Verfasst: Sonntag 11. Dezember 2005, 10:15
von helmut
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.

Verfasst: Sonntag 11. Dezember 2005, 10:32
von Ronnie
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.

Verfasst: Sonntag 11. Dezember 2005, 12:34
von Ronnie
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)

Verfasst: Sonntag 11. Dezember 2005, 22:07
von 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.

Verfasst: Montag 12. Dezember 2005, 19:39
von ich1988
danke

Verfasst: Montag 28. April 2008, 18:09
von sea-live
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()

Verfasst: Montag 28. April 2008, 18:33
von EyDu
Dir ist schon klar, von wann der Thread ist, oder :-) ? Außerdem würde man statt deinem Lambda-Ausdruck 'operator.itemgetter("Date")' verwenden.

Verfasst: Montag 28. April 2008, 18:34
von ne0h
2 1/2 Jahre später... ?

LOL :lol:


ne0h

Verfasst: Montag 28. April 2008, 18:59
von sea-live
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

Verfasst: Montag 28. April 2008, 19:02
von EyDu

Code: Alles auswählen

import operator
data.sort(key=operator.itemgetter("Date"))

Verfasst: Montag 28. April 2008, 19:08
von sea-live
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()

Verfasst: Montag 28. April 2008, 19:46
von Trundle
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.

Verfasst: Montag 28. April 2008, 20:43
von Leonidas
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.

Verfasst: Montag 28. April 2008, 20:45
von EyDu
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.

Verfasst: Dienstag 29. April 2008, 07:51
von sea-live
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

Verfasst: Dienstag 29. April 2008, 08:35
von birkenfeld
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.

Verfasst: Dienstag 29. April 2008, 11:01
von EyDu
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.

Verfasst: Dienstag 29. April 2008, 12:58
von sea-live
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!