2016-10-17 4 views
1

ich diesen Code geschrieben haben:Sortierung dict Artikel von Schlüssel, über alphanumerische Sortierung

n=5 
dizN={} 
for q in range(0,n+1): 
    h=n-q 
    dizN['a'+str(q)+'p'+str(h)]=0 

, dass ein solches Wörterbuch erstellt:

dizN

Out[120]: {'a0p5': 0, 'a1p4': 0, 'a2p3': 0, 'a3p2': 0, 'a4p1': 0, 'a5p0': 0} 

Beachten Sie, dass "n" das ist Grundparameter für meinen Code. Wie Sie sehen können, ist die Summe der Integer, die in dict keys string vorhanden sind, immer = n (= 5 in diesem Fall, wobei n = 5).

Es ist wichtig für mich (für schwierigere Zwecke in meinem Programm), dass für jeden n jedermann wählen kann, die dict auf diese Weise bestellt:

{'a0p(n)': 0, 'a1p(n-1)': 0, ....., 'a(n-1)p1': 0, 'a(n)p0': 0} 

Mein Code ist in Ordnung, aber nur für n < 10. ist n> = 10, das ist, was passiert: (n = 12) dizN:

Out[121]: 
    {'a0p12': 0, 
    'a10p2': 0, 
    'a11p1': 0, 
    'a12p0': 0, 
    'a1p11': 0, 
    'a2p10': 0, 
    'a3p9': 0, 
    'a4p8': 0, 
    'a5p7': 0, 
    'a6p6': 0, 
    'a7p5': 0, 
    'a8p4': 0, 
    'a9p3': 0} 

Wie Sie der Dolmetscher folgt alphanumerische Sortierung sehen können;

Weiß jemand, ob es eine Möglichkeit ist, die gleiche dict sortiert diese Art und Weise zu erhalten:

{'a0p12': 0, 
'a1p11': 0, 
'a2p10': 0, 
'a3p9': 0, 
'a4p8': 0, 
'a5p7': 0, 
'a6p6': 0, 
'a7p5': 0, 
'a8p4': 0, 
'a9p3': 0, 
'a10p2': 0, 
'a11p1': 0, 
'a12p0': 0} 

?

Ich weiß, dass Wörterbücher im Grunde nicht sortierbar sind, aber ich hoffe, dass jemand etwas Trick kennt meinen Zweck sowieso zu erhalten :)

Vielen Dank!

+0

Sie schreiben mehrmals über ein Wörterbuch der Bestellung, aber Python Wörterbücher kann nicht bestellt werden. Vielleicht sollten Sie sich 'OrderedDict' anschauen. –

+0

Der ganze Sinn eines Wörterbuchs ist, dass es nicht geordnet ist. Es ist eine Hashtabelle. – Daniel

+0

Das Sortierkriterium, dem ich folgen möchte, ist "einfach" durch die erste Ganzzahl in dict keys strings, die als Integer (nicht String) aufsteigend betrachtet wird. Oder, um besser zu erklären, durch die ganze Zahl, die dem Buchstaben 'a' in den Strings folgt, die die Schlüssel meines Diktats sind: 'a (ganze Zahl) p (ganze Zahl)'. –

Antwort

1

dicts sind ungeordnete, so die Reihenfolge Sie die Einzelteile zu sortieren gehen zu bekommen zu haben und eine OrderedDict verwenden, um die sortierten Reihenfolge zu halten. Um die Reihenfolge Sie möchten, können Sie Tupel aus den Gruppen von ganzen Zahlen, so dass Sie sortieren als ganze Zahlen in lexikographische Ordnung schaffen:

from itertools import groupby 
from collections import OrderedDict 
d = {'a0p12': 0, 'a10p2': 0, 'a11p1': 0, 'a12p0': 0, 'a1p11': 0, 'a2p10': 0, 
    'a3p9': 0, 'a4p8': 0, 'a5p7': 0, 'a6p6': 0, 'a7p5': 0, 'a8p4': 0, 'a9p3': 0} 

def key_func(x): 
    """'a0p12' -> (0, 12)""" 
    return tuple(int("".join(v)) for k,v in groupby(x[0], key=str.isdigit) if k) 
od = OrderedDict(sorted(d.items(), key=key_func)) 

print(od) 

Was würde Ihnen:

OrderedDict([('a0p12', 0), ('a1p11', 0), ('a2p10', 0), ('a3p9', 0), 
('a4p8', 0), ('a5p7', 0), ('a6p6', 0), ('a7p5', 0), ('a8p4', 0), 
('a9p3', 0), ('a10p2', 0), ('a11p1', 0), ('a12p0', 0)]) 

Sie können auch eine Verwendung regex die Zifferngruppen zu finden:

from collections import OrderedDict 
import re 

d = {'a0p12': 0, 'a10p2': 0, 'a11p1': 0, 'a12p0': 0, 'a1p11': 0, 'a2p10': 0, 
    'a3p9': 0, 'a4p8': 0, 'a5p7': 0, 'a6p6': 0, 'a7p5': 0, 'a8p4': 0, 'a9p3': 0} 



def key_func(x,patt=re.compile("\d+")): 
    """'a0p12' -> (0, 12)""" 
    return tuple(map(int, patt.findall(x[0]))) 

od = OrderedDict(sorted(d.items(), key=key_func)) 

print(od) 
+0

Vielen Dank Padraic! Ich werde diese schöne Lösung in meinem Programm versuchen, dann werde ich eine andere Frage für das größte Problem stellen, das dieses seltsame Sortierbedürfnis beinhaltet! :) –

+0

Keine Sorge, sind die Buchstaben immer gleich und in der gleichen Reihenfolge oder müssen sie berücksichtigt werden? –

+1

Kein solches Problem mit Buchstaben. Die dict keys Form ist immer: –

Verwandte Themen