简体   繁体   中英

python sort a two-level defaultdict and return defaultdict or dict

I have a question about sort defaultdict in python

Assume I have the following codes:

a = defaultdict(defaultdict)
a['c']['C'] = 1
a['b']['B'] = 2
a['a']['A'] = 3
a['a']['AA'] = 4

I'd like to sort it by the first key and then get another sorted defaultdict like

a['a']['A'] = 3
a['a']['AA'] = 4
a['b']['B'] = 2
a['c']['C'] = 1

I've tried using sorted(a.iteritems()) and then get another list. However I need to get dict because I have to iter them.

How can I do this?

for k1 in sorted(a.keys()):
   sub = a[k1]
   for k2 in sorted(sub.keys()):
     print k1, k2, sub[k2] # or do whatever else

This prints the keys and values sorted as you want.

Looks like you just miss-using dictionaries. Do you need to access values by key?

If True use OrderedDict else you don't need dictionaries ;) use lists instead:

>>> a = [['c', 'C', 1],
...      ['b', 'B', 2],
...      ['a', 'A', 3],
...      ['a', 'AA', 4]]
>>> sorted(a, key=lambda entry: entry[1])
[['a', 'A', 3], ['a', 'AA', 4], ['b', 'B', 2], ['c', 'C', 1]]

@Ismail is right - unless you are doing retrieval-before-insert, you really don't need defaultdict. I will assume you are doing something like:

from collections import defaultdict

a = defaultdict(lambda: defaultdict(int))

for x,y in (
    ('c','C'),
    ('a','AA'),
    ('a','A'),
    ('a','AA'),
    ('b','B'),
    ('a','AA')
    # etc
):
    a[x][y] += 1

Here is an iterator that does what you want:

def sortedRecursiveDictIter(d, key=None, prekey=None):
    if isinstance(d,dict):
        if prekey is None:
            prekey = tuple()
        keylist = d.keys()
        keylist.sort(key=key)
        for k in keylist:
            for nk,ni in sortedRecursiveDictIter(d[k], key, prekey+tuple([k])):
                yield nk,ni
    else:
        yield prekey,d

for k,i in sortedRecursiveDictIter(a):
    print k,i

returns

('a', 'A') 3
('a', 'AA') 4
('b', 'B') 2
('c', 'C') 1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM