?Does Python have sorting via "Dictionary Order"?

Andrew Dalke dalke at acm.org
Thu Jun 29 01:10:24 EDT 2000


Norman Shelley wrote in message <395A92D0.65A205B1 at email.sps.mot.com>...
>Does Python have sorting via "Dictionary Order"?  This would be a very
>handy addition as an option to list's sort() function.


No it doesn't that option, and no it won't be a handy addition to the
built-in sort() function.
string
There are many other sorts you may want, like case-insensitive
order or reversed order.  They can't all go into Python's core.
Instead, you can pass a comparison function into sort to make it
work the way you want it to, so the better solution is to build
up a library of sort functions.

For example, here is a way to get what you want.  The 'normalize'
function converts the string into a list of words in normal term.
Letters are converted to lower(letter)+letter.  This forces letters
to be put in the same place, but with caps first.  Numbers are pulled
out into integers.

import string

def normalize(s):
  terms = []
  tmp = ""
  flg = -1  # 0 for string, 1 for integer, -1 for undecided
  for c in s:
    if c in "0123456789":
        if flg == 0:
           terms.append(tmp)
           tmp = c
        else:
           tmp = tmp + c
        flg = 1
    else:
        if flg == 1:
           terms.append(int(tmp))
           tmp = string.lower(c) + c
        else:
           tmp = tmp + string.lower(c) + c
        flg = 0
  if flg == 1:
      terms.append(int(tmp))
  else:
      terms.append(tmp)
  return terms

For examples:
>>> normalize("abc")
aabbcc
>>> dictionary_sort.normalize("Abc")
aAbbcc
>>> dictionary_sort.normalize("x10y")
['xx', 10, 'yy']
>>> dictionary_sort.normalize("x9y")
['xx', 9, 'yy']

So normalize converts the word into something which can be compared
with Python's normal comparison method.

Then to compare two words using the dictionary comparison:

def dictionary_compare(x, y):
  return cmp(normalize(x), normalize(y))

This comparison function can be passed into the list's sort() method

>>> words = ["abc", "Abc", "aBc", "x10y", "x9y"]
>>> words.sort(dictionary_compare)
>>> words
['Abc', 'aBc', 'abc', 'x9y', 'x10y']

For long lists there is a lot of overhead because words are normalized
multiple times.  You can get around that with:

def dictionary_sort(data):  # untested!
  terms = []
  for element in data:
   terms.append( (normalize(element), element) )
  terms.sort()
  data = []
  for element in terms:
    data.append(element[1])
  return data

For more info on this trick, see
  http://python.org/doc/howto/sorting/sorting.html

                    Andrew
                    dalke at acm.org






More information about the Python-list mailing list