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

Raymond Hettinger vze4rx4y at verizon.net
Thu May 29 16:34:54 EDT 2003


"George Young" <gry at ll.mit.edu> wrote in message
news:pan.2003.05.29.19.11.15.218757 at ll.mit.edu...
> [python 2.3a1]
> 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.e., a name is an integer or an alphabetic prefix possibly followed
> by an integer.  The display must compress each set of succesive names
> having the same (possibly null) prefix and sequential integers.  The
> original order of names must be preserved.
>
> I (hesitantly) post the following code that works, but makes me cringe
> anytime I see it, for it's clumsy unreadableness.  Can someone with
> a fresh mind see a clear and concise way to make my clear and concise
> name display?

It helps to separate the problem into parsing, grouping, and output formatting:

# input parsing
import re
numb = re.compile('(\D*)(\d*)')
names = ['6','7','mx8','mx09','mx10','8','9','10','foo']
pairs = [numb.match(n).groups() for n in names]

# grouping
result = []
currobj, currnum, cnt = None, "", 0
for obj, num in pairs:
    if obj == currobj:
        cnt += 1
    else:
        result.append((currobj, currnum, cnt))
        currobj, currnum, cnt = obj, num, 1
result.append((currobj, currnum, cnt))

# output formatting
for obj, num, cnt in result[1:]:
    if cnt == 1: print obj + num
    else: print obj + num + '-' + str(int(num)+cnt)


Raymond Hettinger






More information about the Python-list mailing list