defaultdict(list) sortieren

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
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

Hallo,
Ich habe ein defauldict(list) wobei die Liste beinhaltet dicts.

Code: Alles auswählen

from operator import itemgetter
from collections import defaultdict
import pprint

a = defaultdict(list)

a[1] = [{ 'a':3, 'b':1, 'c':3},{'a':2, 'b':1, 'c':3}, { 'a':0, 'b':1, 'c':3}]
a[2] = [{ 'a':6, 'b':1, 'c':3},{'a':4, 'b':1, 'c':3}, { 'a':5, 'b':1, 'c':3}]

for key in a:
    a[key] = sorted(a[key], key=itemgetter('a')) 
    
pprint.pprint(a)
Ich war in der lange die Liste zu sortieren aber ich bin mir nicht sicher ob es die beste Loesung ist?
Benutzeravatar
pillmuncher
User
Beiträge: 1529
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Es ist schon fast optimal. So ist es noch besser:

Code: Alles auswählen

from operator import itemgetter
from collections import defaultdict
import pprint

a = defaultdict(list)

a[1] = [{ 'a':3, 'b':1, 'c':3},{'a':2, 'b':1, 'c':3}, { 'a':0, 'b':1, 'c':3}]
a[2] = [{ 'a':6, 'b':1, 'c':3},{'a':4, 'b':1, 'c':3}, { 'a':5, 'b':1, 'c':3}]

a_key = itemgetter('a')

for each in a.values():
    each.sort(key=a_key)

pprint.pprint(a)
In specifications, Murphy's Law supersedes Ohm's.
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

Danke, es funktioniert.

Wie könnte man nur den höchsten Wert speichern?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Du meinst analog zur sort-Funktion? Mittels max.
Das Leben ist wie ein Tennisball.
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

Habe ich versucht, aber ich bekomme "each.max(key=a_key) AttributeError: 'list' object has no attribute 'max'".

Code: Alles auswählen

    from operator import itemgetter
    from collections import defaultdict
    import pprint
     
    a = defaultdict(list)
     
    a[1] = [{ 'a':3, 'b':1, 'c':3},{'a':2, 'b':1, 'c':3}, { 'a':0, 'b':1, 'c':3}]
    a[2] = [{ 'a':6, 'b':1, 'c':3},{'a':4, 'b':1, 'c':3}, { 'a':5, 'b':1, 'c':3}]
     
    a_key = itemgetter('a')
     
    for each in a.values():
        each.max(key=a_key)
     
    pprint.pprint(a)
Benutzeravatar
pillmuncher
User
Beiträge: 1529
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@mit:

Code: Alles auswählen

>>> max_items = [max(each, key=a_key) for each in a.values()]
>>>
>>> pprint.pprint(max_items)
[{'a': 3, 'b': 1, 'c': 3}, {'a': 6, 'b': 1, 'c': 3}]
In specifications, Murphy's Law supersedes Ohm's.
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

Danke, es funktioniert fast, aber wie bekommt folgendes hin?

Code: Alles auswählen

{1: [{'a': 3, 'c': 3, 'b': 1}], 2: [{'a': 6, 'c': 3, 'b': 1}]}
or
defaultdict(<type 'list'>, {1: [{'a': 3, 'c': 3, 'b': 1}], 2: [{'a': 6, 'c': 3, 'b': 1}]})
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Was soll denn da passieren? Willst du die Einträge durchnummerieren? Ich hoffe doch nicht, denn dann solltest du Listen oder Tupel verwenden.
Das Leben ist wie ein Tennisball.
Benutzeravatar
pillmuncher
User
Beiträge: 1529
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

In specifications, Murphy's Law supersedes Ohm's.
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

Ich kam ab mit dieser loesung, aber ich weiss nicht ob es die schnellste ist:

Code: Alles auswählen

from operator import itemgetter
from collections import defaultdict
import pprint
 
a = defaultdict(list)
 
a[1] = [{ 'a':3, 'b':1, 'c':3},{'a':2, 'b':1, 'c':3}, { 'a':0, 'b':1, 'c':3}]
a[2] = [{ 'a':6, 'b':1, 'c':3},{'a':4, 'b':1, 'c':3}, { 'a':5, 'b':1, 'c':3}]
 
a_key = itemgetter('a')
 
for each in a.values():
    each.sort(key=a_key)
 
pprint.pprint(a)

# verkleinern
b = defaultdict(dict)
for k, v in a.items():
    b[k] = v[0]

pprint.pprint(b)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Bezüglich der Zeitkomplexität handelst Du Dir durch das Sortieren O(n * log n) ein. Das ließe sich optimieren, indem Du einfach die ``min``-Funktion für jede Value-Liste in ``a`` anwendest. Die hat nur O(n), ist also bei vielen Elementen deutlich schneller:

Code: Alles auswählen

# mal für ein value-Element:
min(a[1], key=itemgetter("a"))
>  {'a': 0, 'b': 1, 'c': 3}
Edit: Aufbauend auf dem bisherigen Code komme ich darauf:

Code: Alles auswählen

b = {k: min(v, key=a_key) for k, v in a.items()}
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@mit: Das schnellste wofür? Falls Du nur `b` als Endergebnis haben möchtest und die Listen nirgends wirklich sortiert benötigst, dann wäre `max()` (für die ursprünglich gezeigten gewünschten Ergebnisdaten) oder `min()` (für das Ergebnis des letzten Codebeispiels) schneller, weil dann nur linear durch die Listen gegangen werden muss statt sie zu sortieren.
mit
User
Beiträge: 285
Registriert: Dienstag 16. September 2008, 10:00

Danke es funktioniert;

Code: Alles auswählen

from operator import itemgetter
from collections import defaultdict
import pprint
 
a = defaultdict(list)
 
a[1] = [{ 'a':3, 'b':1, 'c':3},{'a':2, 'b':1, 'c':3}, { 'a':0, 'b':1, 'c':3}]
a[2] = [{ 'a':6, 'b':1, 'c':3},{'a':4, 'b':1, 'c':3}, { 'a':5, 'b':1, 'c':3}]
 
# verkleinern
a_key = itemgetter('a')
b = defaultdict(dict)
b = {k: min(v, key=a_key) for k, v in a.items()}
BlackJack

@mit: Zeile 12 ist sinnfrei.
Antworten