Seite 1 von 1

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

Verfasst: Mittwoch 14. Dezember 2005, 10:35
von jens
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...

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

Verfasst: Mittwoch 14. Dezember 2005, 13:09
von Gast
Was ist denn jetzt deine frage?
joe

Verfasst: Mittwoch 14. Dezember 2005, 13:42
von jens
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)

Verfasst: Mittwoch 14. Dezember 2005, 14:22
von joe
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

Verfasst: Mittwoch 14. Dezember 2005, 15:10
von jens
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...

Verfasst: Donnerstag 15. Dezember 2005, 00:12
von BlackJack
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`.

Verfasst: Donnerstag 15. Dezember 2005, 07:30
von jens
Guter Tipp, da gettext immer noch in meinem Hinterkopf herum schwirrt ;)

Verfasst: Donnerstag 15. Dezember 2005, 09:19
von mitsuhiko
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.

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

Verfasst: Donnerstag 14. Februar 2013, 21:27
von Jasmina
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

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

Verfasst: Donnerstag 14. Februar 2013, 21:38
von cofi
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.

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

Verfasst: Freitag 15. Februar 2013, 08:45
von /me
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.

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

Verfasst: Freitag 15. Februar 2013, 10:43
von BlackJack
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.

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

Verfasst: Freitag 22. Februar 2013, 19:53
von Jasmina
Merci vielmals :D

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