Seite 1 von 1

defaultdict(list) sortieren

Verfasst: Montag 11. August 2014, 02:07
von mit
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?

Re: defaultdict(list) sortieren

Verfasst: Montag 11. August 2014, 02:42
von pillmuncher
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)

Re: defaultdict(list) sortieren

Verfasst: Montag 11. August 2014, 13:19
von mit
Danke, es funktioniert.

Wie könnte man nur den höchsten Wert speichern?

Re: defaultdict(list) sortieren

Verfasst: Montag 11. August 2014, 13:20
von EyDu
Du meinst analog zur sort-Funktion? Mittels max.

Re: defaultdict(list) sortieren

Verfasst: Montag 11. August 2014, 14:10
von mit
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)

Re: defaultdict(list) sortieren

Verfasst: Montag 11. August 2014, 14:27
von pillmuncher
@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}]

Re: defaultdict(list) sortieren

Verfasst: Montag 11. August 2014, 14:45
von mit
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}]})

Re: defaultdict(list) sortieren

Verfasst: Montag 11. August 2014, 15:14
von EyDu
Was soll denn da passieren? Willst du die Einträge durchnummerieren? Ich hoffe doch nicht, denn dann solltest du Listen oder Tupel verwenden.

Re: defaultdict(list) sortieren

Verfasst: Montag 11. August 2014, 16:34
von pillmuncher

Re: defaultdict(list) sortieren

Verfasst: Dienstag 12. August 2014, 13:50
von mit
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)

Re: defaultdict(list) sortieren

Verfasst: Dienstag 12. August 2014, 14:02
von Hyperion
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()}

Re: defaultdict(list) sortieren

Verfasst: Dienstag 12. August 2014, 14:02
von 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.

Re: defaultdict(list) sortieren

Verfasst: Dienstag 12. August 2014, 14:21
von mit
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()}

Re: defaultdict(list) sortieren

Verfasst: Dienstag 12. August 2014, 14:24
von BlackJack
@mit: Zeile 12 ist sinnfrei.