471,092 Members | 1,148 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,092 software developers and data experts.

Print dict in sorted order

I have a code snippet here that prints a dict in an arbitrary order.
(Certain keys first, with rest appearing in sorted order). I didn't
want to subclass dict, that's error-prone, and overkill for my needs. I
just need something that returns a value like dict.__str__, with a key
ordering I specify.

If you have any opinions on how it could be made better, I'm all ears!

def DictToString(d, preferred_order = ['gid', 'type',
'parent', 'name']):
' Return a string containing the sorted dict'
keys = d.keys()
keys.sort()
sortmax = len(preferred_order)
for i in range(sortmax-1, -1, -1):
sortkey = preferred_order[i]
try:
index = keys.index(sortkey)
except ValueError:
continue
temp = keys[index]
del keys[index]
keys.insert(0, temp)
s = []
s.append('{')
max = len(keys)
for i in range(max):
key = keys[i]
val = d[key]
s.append(repr(key))
s.append(': ')
s.append(repr(val))
if i < max-1:
s.append(', ')
s.append('}')
return ''.join(s)
def main():
d = {'whatever': 145,
'gid': 12345678901234567890,
'name': 'Name',
'type': 'an egg',
32: 'Thirty-two (32)'}

# Convert dicts to strings
s1 = str(d)
s2 = DictToString(d)
print "Python str:", s1
print "Custom str:", s2

# Verify the strings are different
assert(s1 != s2)

# Convert the strings back to dicts
d1 = eval(s1)
d2 = eval(s2)

# Verify the dicts are equivalent
assert(d1 == d2)

print "\nSuccess!\n"

main()

Jan 29 '06 #1
6 5322
"Kamilche" <kl*******@comcast.net> writes:
I have a code snippet here that prints a dict in an arbitrary order.
(Certain keys first, with rest appearing in sorted order). I didn't
want to subclass dict, that's error-prone, and overkill for my needs. I
just need something that returns a value like dict.__str__, with a key
ordering I specify.

If you have any opinions on how it could be made better, I'm all ears!


Here's my version. Obviously you could save a line or two here and
there, depending on your stylistic preference.

================================================== ==============

from sets import Set
from cStringIO import StringIO

def DictToString(d, preferred_order = ['gid', 'type',
'parent', 'name']):
r = StringIO()
def out(k, v):
r.write('%s:%s,'% (repr(k), repr(v)))
r.write('{')
for k in preferred_order:
if k in d:
out(k, d[k])
for k in sorted([k1 for k1 in d.keys() if k1 not in Set(preferred_order)]):
out(k, d[k])
r.write('}')
return r.getvalue()
Jan 29 '06 #2
You can always use OrderedDict :

htttp://www.voidspace.org.uk/python/odict.html

from odict import OrderedDict
my_dict = OrderedDict(some_dict.keys())
keys = my_dict.keys()
keys.sort()
my_dict.setkeys(keys)
print my_dict

Of course if your ordering requirement was *that* trivial, you could do
:

from odict import OrderedDict
my_dict = OrderedDict(some_dict.keys())
my_dict.sort()

*Or* you can do :

from odict import SequenceOrderedDict
my_dict = SequenceOrderedDict(some_dict.keys())
keys = my_dict.keys()
keys.sort()
my_dict.keys = keys
print my_dict

All the best,

Fuzzyman
http://www.voidspace.org.uk/python/index.shtml

Jan 29 '06 #3
[Kamilche]
I have a code snippet here that prints a dict in an arbitrary order.
(Certain keys first, with rest appearing in sorted order). I didn't
want to subclass dict, that's error-prone, and overkill for my needs. I
just need something that returns a value like dict.__str__, with a key
ordering I specify.

If you have any opinions on how it could be made better, I'm all ears!


Here's one more version to throw in the mix:
from itertools import count, izip

def dict2str(d, preferred_order = ['gid', 'type', 'parent', 'name']):
last = len(preferred_order)
rank = dict(izip(preferred_order, count()))
pairs = d.items()
pairs.sort(key=lambda (k,v): rank.get(k, (last, k, v)))
return '{%s}' % repr(pairs)[1:-1]
d = dict(gid=10, type=20, parent=30, name=40, other=50, rest=60)
print dict2str(d)

Raymond

Jan 30 '06 #4
> from itertools import count, izip

def dict2str(d, preferred_order = ['gid', 'type', 'parent', 'name']):
last = len(preferred_order)
rank = dict(izip(preferred_order, count()))
pairs = d.items()
pairs.sort(key=lambda (k,v): rank.get(k, (last, k, v)))
return '{%s}' % repr(pairs)[1:-1]


P.S. If you need the string to evaluatable like repr(d), then change
the last line to:

return 'dict(%r)' % pairs

Jan 30 '06 #5
Raymond Hettinger wrote:
from itertools import count, izip

def dict2str(d, preferred_order = ['gid', 'type', 'parent', 'name']):
last = len(preferred_order)
rank = dict(izip(preferred_order, count()))
pairs = d.items()
pairs.sort(key=lambda (k,v): rank.get(k, (last, k, v)))
return '{%s}' % repr(pairs)[1:-1]


P.S. If you need the string to evaluatable like repr(d), then change
the last line to:

return 'dict(%r)' % pairs

or:

def dict2str(d, preferred_order = ['gid', 'type', 'parent', 'name']):
pairs = [(item, d[item]) for item in preferred_order]
#preferred_order = set(preferred_order) # if preferred_order is big
pairs.extend(sorted((k, v) for k,v in d.iteritems() if k not in
preferred_order))
return '{%s}' % repr(pairs)[1:-1]

Michael

Jan 30 '06 #6
Use the seqdict.py package:

What is it?
http://home.arcor.de/wolfgang.grafen...s/DOC/seqdict/

Downloads:
http://home.arcor.de/wolfgang.grafen...eqdict-0.3.zip
http://home.arcor.de/wolfgang.grafen...ML/HTMLDoc.zip
http://home.arcor.de/wolfgang.grafen...L/Seqdict.html
http://home.arcor.de/wolfgang.grafen.../Mseqdict.html

Sorry, this link is broken - have to fix it asap.
http://home.arcor.de/wolfgang.grafen...s/Modules.html

seqdict.py has been successfully used in several projects... and it is *easy* and
flexible.

Regards

Wolfgang

Kamilche wrote:
I have a code snippet here that prints a dict in an arbitrary order.
(Certain keys first, with rest appearing in sorted order). I didn't
want to subclass dict, that's error-prone, and overkill for my needs. I
just need something that returns a value like dict.__str__, with a key
ordering I specify.

SNIP
Jan 30 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

6 posts views Thread by Rick Morrison | last post: by
23 posts views Thread by stewart.midwinter | last post: by
7 posts views Thread by Marcio Rosa da Silva | last post: by
2 posts views Thread by cheng | last post: by
7 posts views Thread by pauld | last post: by
9 posts views Thread by py | last post: by
12 posts views Thread by Florian Brucker | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.