[2,3,4,7] --> "2-4,7" ?

Manuel Garcia news at manuelmgarcia.com
Fri May 30 13:42:08 EDT 2003


On Thu, 29 May 2003 15:11:21 -0400, George Young <gry at ll.mit.edu>
wrote:

>I have a list of "names" like:
>  ['6','7','mx8','mx09','mx10','8','9','10','foo']
>which needs for concise and clear display to become a string like:
>
>  "6-7,mx8-10,8-10,foo"

I also see from your subject line that
	[2,3,4,7] --> "2-4,7"
I am not sure all the code given before took this into account.

I was thinking about this problem since yesterday, because I have
coded similar stuff at least a dozen times in my life, but I had not
yet found a good way to do it.

I tried Python OO, and I think it turned out pretty clean.

###############################
## gyoung.py

import re

class GroupHelper:
    def __init__(self, s='', **d):
        m = re.match(r'(\D*)(\d+)$', s)
        if m:
            g = m.groups()
            self.kind = 'pair'
            self.prefix = g[0]
            self.start = self.end = int(g[1])
        else:
            self.kind = 'string'
            self.prefix = s
        self.__dict__.update(d)
    def __add__(self, other):
        if (self.kind != 'pair') or (other.kind != 'pair'):
            raise TypeError
        if self.prefix != other.prefix:
            raise TypeError
        if other.start != (self.end + 1):
            raise TypeError
        return GroupHelper(
            kind='pair',
            prefix=self.prefix,
            start=self.start,
            end=other.end)
    def __str__(self):
        if self.kind == 'string':
            return self.prefix
        if self.start == self.end:
            return '%s%i' % (self.prefix, self.start)
        return '%s%i-%i' % (self.prefix, self.start, self.end)        

def gyoung(list0):
    if not list0: return ''
    list0 = [GroupHelper(s) for s in list0]
    result = [list0[0]]
    for gh in list0[1:]:
        try:
            result[-1] += gh
        except TypeError:
            result.append(gh)
    return ','.join( [str(y) for y in result] )

print gyoung(
    ['6','7','8','12','mx8','mx09','mx10','8','9','10','foo'])

###############################

The main loop is particularly clean, because the class does all the
work.

In the other solutions given, I was worried about what always happened
to me the other dozen times I coded something like this: if there is a
small change to the specification, my old algorithm cannot be simply
adapted.

For example, if you wanted 'foo' to be treated like 'foo00', or if in
the original list, you already had some items in the form
	'mx8-12, mx13, mx14-17'
and you wanted the result to be 'mx8-17'
I think with this Python OO approach, you can make such changes
simply.  Local changes to the parsing, 'adding', formatting, or the
main loop don't seem to necessitate a global change to the code.

The Perl solution was hilarious! I assume it was done tongue-in-cheek.

Manuel




More information about the Python-list mailing list