Sort Streets by Name Using Python

Update 13Oct2015: Webucator detailed and improved this solution. Take a look!.

North Davidson Street, Naramore Street and Davidson Street, if sorting street names, these streets should be together. However, if these street names are in a list and sorted alphabetically, North Davidson will be placed in with Naramore, nowhere near Davidson in the sort order.

This is the problem posed by a colleage yesterday. To be fair, he had already solved the problem, but it sounded interesting. Giving in to my inner geek, I sat down last night after dinner and figured it out.

For those of you with a short attention span, here is the finished solution.

Breaking this down, the steps are:

  1. Use regular expression (pattern) matching to separate the cardinal direction prefix if present. This first snippet just creates the compiled regular expression.

    regex = re.compile(
        r'(?P<prefix>^North\w*\s|^South\w*\s|^East\w*\s|^West\w*\s|^N\.?\s|^S\.?\s|^E\.?\s|^W\.?\s)?(?P<street>.*)',
        re.IGNORECASE
    )
    

    Lower down in the script, the named groups are extracted and converted to lower case to make sure sorting works as expected.

      street_match = regex.search(street)
      if street_match.group('prefix'):
        street_prefix = street_match.group('prefix')
      street_root = street_match.group('street')
    
  2. Create a list of three part tuples consisting of prefix, street name and the original string.

    street_sort_list.append((street_prefix, street_root, street))
    
  3. Sort these tuples first using the street name and if the street name is the same, then the cardinal direction.

    street_sort_list.sort(key=itemgetter(1, 0), reverse=False)
    
  4. Return a list of just the original street name strings sorted based on street name, not the possible direction prefix. This snippet takes advantage of a list comprehension to create this list.

    return [street_tuple[2] for street_tuple in street_sort_list]
    

If you are interested in digging deeper into any of the pieces used to create this function, here are the references I used.

Hopefully you find this useful. At the very least, it does provide an interesting question for problem solving. After completing this, exploring this solution feels not altogether different than a college homework assignment. Although potentially useuful, it did not solve a relevant need for something I need to do. Still, I learned a lot from it! Hence, hopefully you find this page in your search for a real solution and put it to productive use.