Print dict in sorted order

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Kamilche

    #1

    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_o rder)
    for i in range(sortmax-1, -1, -1):
    sortkey = preferred_order[i]
    try:
    index = keys.index(sort key)
    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(k ey))
    s.append(': ')
    s.append(repr(v al))
    if i < max-1:
    s.append(', ')
    s.append('}')
    return ''.join(s)


    def main():
    d = {'whatever': 145,
    'gid': 123456789012345 67890,
    '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()

  • Paul Rubin

    #2
    Re: Print dict in sorted order

    "Kamilche" <klachemin@comc ast.net> writes:
    [color=blue]
    > 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![/color]

    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_o rder)]):
    out(k, d[k])
    r.write('}')
    return r.getvalue()

    Comment

    • Fuzzyman

      #3
      Re: Print dict in sorted order

      You can always use OrderedDict :

      htttp://www.voidspace.o rg.uk/python/odict.html

      from odict import OrderedDict
      my_dict = OrderedDict(som e_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(som e_dict.keys())
      my_dict.sort()

      *Or* you can do :

      from odict import SequenceOrdered Dict
      my_dict = SequenceOrdered Dict(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

      Comment

      • Raymond Hettinger

        #4
        Re: Print dict in sorted order

        [Kamilche][color=blue]
        > 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![/color]

        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_o rder)
        rank = dict(izip(prefe rred_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

        Comment

        • Raymond Hettinger

          #5
          Re: Print dict in sorted order

          > from itertools import count, izip[color=blue]
          >
          > def dict2str(d, preferred_order = ['gid', 'type', 'parent', 'name']):
          > last = len(preferred_o rder)
          > rank = dict(izip(prefe rred_order, count()))
          > pairs = d.items()
          > pairs.sort(key= lambda (k,v): rank.get(k, (last, k, v)))
          > return '{%s}' % repr(pairs)[1:-1][/color]

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

          return 'dict(%r)' % pairs

          Comment

          • Michael Spencer

            #6
            Re: Print dict in sorted order

            Raymond Hettinger wrote:[color=blue][color=green]
            >> from itertools import count, izip
            >>
            >> def dict2str(d, preferred_order = ['gid', 'type', 'parent', 'name']):
            >> last = len(preferred_o rder)
            >> rank = dict(izip(prefe rred_order, count()))
            >> pairs = d.items()
            >> pairs.sort(key= lambda (k,v): rank.get(k, (last, k, v)))
            >> return '{%s}' % repr(pairs)[1:-1][/color]
            >
            > P.S. If you need the string to evaluatable like repr(d), then change
            > the last line to:
            >
            > return 'dict(%r)' % pairs
            >[/color]
            or:

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

            Michael

            Comment

            • Wolfgang Grafen

              #7
              Re: Print dict in sorted order

              Use the seqdict.py package:

              What is it?


              Downloads:





              Sorry, this link is broken - have to fix it asap.


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

              Regards

              Wolfgang

              Kamilche wrote:[color=blue]
              > 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.
              >[/color]
              SNIP

              Comment

              Working...