naive string question

Manuel Garcia news at manuelmgarcia.com
Wed Mar 5 04:06:31 CET 2003


On Wed, 5 Mar 2003 00:41:18 +0000 (UTC), Micha³ Kurowski
<mkur at poczta.gazeta.pl> wrote:
(edit)
>I'm looking for a fast and elegant way of mapping a string to a list
>based on changes in the string (something like 'aaa-ab-a-bbbaa').
>
>So far I've got this:
>
>b= []
>for i in range(1, len(a)):
>    if a[i] != a[i-1]:
>        b.append((i, a[i-1]))
>
>It's truly the first thing that came to my mind.
>(Perhaps a bit influenced by not so good performance-wise 
>experience with functional programming tools ;-).

First of all, please don't worry about your code's performance.  The
first thing that came to your mind is a perfectly excellent way to do
it.

Perhaps what you really want is a run length encoding of your string,
where we note the character and how many times the character is
repeated.

Here are 2 versions of run length encoding, one with the index of the
first character, similar to what your code returns:

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

import sys
import pprint

class _print_indent:
    def write(self, s):
        if s.endswith('\n'): s = s[:-1]
        s = ('\n%s\n' % (s,)).replace('\n','\n    ')[1:-4]
        sys.stdout.write(s)
print_indent = _print_indent()

def _print_execute(e):
    f = sys._getframe(1)
    try:
        r = eval(e, f.f_globals, f.f_locals)
    except SyntaxError:
        exec e in f.f_globals, f.f_locals
        print e
    else:
        print '%s ->' % (e,)
        pprint.pprint(r, print_indent)

def print_execute(x):
    [ _print_execute(e) for e in x.split('\n') if e ]

def kurowski(a):
    b= []
    for i in range(1, len(a)):
        if a[i] != a[i-1]:
            b.append((i, a[i-1]))
    return b

def run_length_encode1(a):
    b = [ ['',-1] ]
    for c in a:
        if c != b[-1][0]:
            b.append( [c, 1] )
        else:
            b[-1][1] += 1
    b.pop(0)
    return [ tuple(x) for x in b ]

def run_length_encode2(a):
    b = [ ['',-1,-1] ]
    for i in range(len(a)):
        c = a[i]
        if c != b[-1][0]:
            b.append( [c, i, 1] )
        else:
            b[-1][2] += 1
    b.pop(0)
    return [ tuple(x) for x in b ]

print_execute("""
kurowski('aaa-ab-a-bbbaa')
run_length_encode1('aaa-ab-a-bbbaa')
run_length_encode2('aaa-ab-a-bbbaa')
""")





More information about the Python-list mailing list