dict nach key-Länge sortiert ausgeben...

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.
Antworten
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 14. Dezember 2005, 10:35

Ich hab ein dict, welches ich gern sortiert nach der Key-Länge ausgeben möchte... Von kürzesten zum längsten Key:

Code: Alles auswählen

{
'real_self_url': '/index.py',
'current_action': '/index.py?page_id=1&command=edit_look&action=edit_internal_page',
'main_action': '/index.py?page_id=1&command=edit_look&action=internal_page',
'base': '/index.py?page_id=1',
'command': '/index.py?page_id=1&command=edit_look',
'action': '/index.py?page_id=1&command=edit_look&action=',
'link': '/index.py?p=',
'poormans_url': '/index.py'
}
Ich gebe es momentan einfach unsortiert aus:

Code: Alles auswählen

  real_self_url: /index.py
 current_action: /index.py?page_id=1&command=edit_look&action=edit_internal_page
    main_action: /index.py?page_id=1&command=edit_look&action=internal_page
           base: /index.py?page_id=1
        command: /index.py?page_id=1&command=edit_look
         action: /index.py?page_id=1&command=edit_look&action=
           link: /index.py?p=
   poormans_url: /index.py
Aber das ist nicht wirklich übersichtlich...

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Gast

Mittwoch 14. Dezember 2005, 13:09

Was ist denn jetzt deine frage?
joe
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 14. Dezember 2005, 13:42

Ich wüste gern, wie ich es am geschicktesten anstellen kann, das Dict, sortiert nach der Länge der Keys, ausgeben zu können...

(Wobei keine 2.4 Features genutzt werden sollten)

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
joe

Mittwoch 14. Dezember 2005, 14:22

jens hat geschrieben:Ich wüste gern, wie ich es am geschicktesten anstellen kann, das Dict, sortiert nach der Länge der Keys, ausgeben zu können...
Also kein sorted. Aber was heißt nun "am geschicktesten"? Ist das dictionary sehr groß, so daß geschwindigkeit ein problem wird? Dann dürfe wohl das DSU-Pattern angesagt sein.

Code: Alles auswählen

d = { 
'real_self_url': '/index.py', 
'current_action': '/index.py?page_id=1&command=edit_look&action=edit_internal_page', 
'main_action': '/index.py?page_id=1&command=edit_look&action=internal_page', 
'base': '/index.py?page_id=1', 
'command': '/index.py?page_id=1&command=edit_look', 
'action': '/index.py?page_id=1&command=edit_look&action=', 
'link': '/index.py?p=', 
'poormans_url': '/index.py' 
} 

items = [(len(k),k,v) for (k,v) in d.items()]
items.sort()
items = [(k,v) for (_,k,v) in items]

for k,v in items:
    print k,v
joe
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 14. Dezember 2005, 15:10

Die Größe ist kein Problem... Es bleibt bei den Umfang, wie die Beispieldaten...

Ich wollte das nach den values sortiert haben, nicht nach den keys (Das hatte ich falsch angegeben). Dein Beispiel bring mich da aber schon mal weiter, ich hab es nochmal etwas gekürzt:

Code: Alles auswählen

d = {
'real_self_url': '/index.py',
'current_action': '/index.py?page_id=1&command=edit_look&action=edit_internal_page',
'main_action': '/index.py?page_id=1&command=edit_look&action=internal_page',
'base': '/index.py?page_id=1',
'command': '/index.py?page_id=1&command=edit_look',
'action': '/index.py?page_id=1&command=edit_look&action=',
'link': '/index.py?p=',
'poormans_url': '/index.py'
}

values = [(len(v),k,v) for k,v in d.iteritems()]
values.sort()

for _,k,v in values:
    print "%15s:%s" % (k,v)
Das mit dem _ kenne ich noch überhaupt nicht...

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

Donnerstag 15. Dezember 2005, 00:12

jens hat geschrieben:

Code: Alles auswählen

for _,k,v in values:
    print "%15s:%s" % (k,v)
Das mit dem _ kenne ich noch überhaupt nicht...
Der Unterstrich ist ein ganz normaler Name wie jeder andere auch. Allerdings verwende ich ihn so nicht, weil es ja immer mal passieren kann, das man die Anwendung mal "internationalisieren" möchte und der Unterstrich ist dann traditionell der Name für die Funktion aus `gettext` die zum Übersetzen von Zeichenketten benutzt wird.

Ich benutze für solche "Wegwerfnamen" immer `dummy`.
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Donnerstag 15. Dezember 2005, 07:30

Guter Tipp, da gettext immer noch in meinem Hinterkopf herum schwirrt ;)

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Donnerstag 15. Dezember 2005, 09:19

Der "_" hat noch eine Funktion:

Code: Alles auswählen

>>> "Das ist die letzte Ausgabe"
'Das ist die letzte Ausgabe'
>>> _
'Das ist die letzte Ausgabe'
Ist aber nur in der interaktiven Shell so.
TUFKAB – the user formerly known as blackbird
Jasmina
User
Beiträge: 10
Registriert: Sonntag 4. November 2012, 15:05

Donnerstag 14. Februar 2013, 21:27

Hallo zusammen,

beim Hilfe-Suche im Netz bin ich auf den folgenden sehr! hilfreichen Ausdruck gestoßen, der bei mir auch wunderbar funktioniert hat :D:

Code: Alles auswählen

items = [(len(k),k,v) for (k,v) in d.items()]
items.sort()
items = [(k,v) for (_,k,v) in items]

for k,v in items:
    print k,v
Da ich allerdings noch nicht sehr lange im Python-Geschäft drin bin, kann ich mir diesen Code noch nicht ganz erklären.
Vielleicht kann mir jemand ihn Schritt für Schritt erklären (damit ich auch weiß was ich da habe :D ).
Das wäre super.

Merci im voraus.
Grüße
Jasmina
Benutzeravatar
cofi
Moderator
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Donnerstag 14. Februar 2013, 21:38

7 Jahre alte Threads ausgraben fällt unter Leichenschändung :roll:

Das kann man aber noch viel einfacher haben:

Code: Alles auswählen

In [1]: d = dict((i*'a', i) for i in range(1, 10))

In [2]: d
Out[2]: 
{'a': 1,
 'aa': 2,
 'aaa': 3,
 'aaaa': 4,
 'aaaaa': 5,
 'aaaaaa': 6,
 'aaaaaaa': 7,
 'aaaaaaaa': 8,
 'aaaaaaaaa': 9}

In [3]: sorted(d.items(), key=lambda p: len(p[0]))
Out[3]: 
[('a', 1),
 ('aa', 2),
 ('aaa', 3),
 ('aaaa', 4),
 ('aaaaa', 5),
 ('aaaaaa', 6),
 ('aaaaaaa', 7),
 ('aaaaaaaa', 8),
 ('aaaaaaaaa', 9)]

In [4]: sorted(d.items(), key=lambda p: len(p[0]), reverse=True)
Out[4]: 
[('aaaaaaaaa', 9),
 ('aaaaaaaa', 8),
 ('aaaaaaa', 7),
 ('aaaaaa', 6),
 ('aaaaa', 5),
 ('aaaa', 4),
 ('aaa', 3),
 ('aa', 2),
 ('a', 1)]
`sorted` sortiert eine sequence, hier die items eines Dictionaries, anhand eines Schlüssels, hier die Länge des ersten Teils des Tupels als dem Dictionary-Schlüsssel.
Benutzeravatar
/me
User
Beiträge: 3192
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Freitag 15. Februar 2013, 08:45

Jasmina hat geschrieben:Vielleicht kann mir jemand ihn Schritt für Schritt erklären

Code: Alles auswählen

items = [(len(k),k,v) for (k,v) in d.items()]
Hier haben wir eine list comprehension. Du könntest dir den Code alternativ so vorstellen.

Code: Alles auswählen

items = []
for k, v in d.items():
    items.append((len(k), k, v))
Hier passiert nichts anderes, als alle Einträge des Dictionaries zu durchlaufen, die Länge des Schlüssels, den Schlüssel und den Wert in ein Tupel zu packen ( (len(k),k,v) ) und das jeweilige Tupel einer neuen Liste namens items hinzuzufügen.

Code: Alles auswählen

items.sort()
Hier wird die Liste mit den Tupeln sortiert. Da die Länge an erster Stelle des Tupels steht ist sie auch das primäre Sortierkriterium.

Code: Alles auswählen

items = [(k,v) for (_,k,v) in items]
Hier wird aus der sortierten Liste jeder Eintrag genommen und eine neue Liste namens items mit Tupeln ohne den Längeneintrag aufgebaut. Jeder Eintrag der sortierten Liste wird dabei in dem Tupel (_, k, v) zurückgeliefert. Der Unterstrich ist ein ganz normaler Bezeichnername der gerne verwendet wird wenn man anzeigen möchte, dass der zugewiesene Wert nicht weiter verwendet wird.


cofis gezeigte Methode ist aber definitiv schöner und mit ein wenig Erfahrung in Python definitiv schneller und einfacher zu lesen als die von dir gezeigte lange Variante.
BlackJack

Freitag 15. Februar 2013, 10:43

Ergänzend dazu funktioniert das Muster, welches cofi gezeigt hat auch wenn die Schlüssel selbst nicht auf grösser/kleiner vergleichbar sind. Der Datentyp `complex` fällt da zum Beispiel drunter.
Jasmina
User
Beiträge: 10
Registriert: Sonntag 4. November 2012, 15:05

Freitag 22. Februar 2013, 19:53

Merci vielmals :D

@cofi: So verschwinden sie nicht in der Versenkung und geraten in Vergessenheit :wink:
Antworten