Converting arrarys in Python to arrays in C

Francis Avila francisgavila at yahoo.com
Wed Dec 17 15:04:30 EST 2003


Simon Foster wrote in message
<3fe06b14$0$25662$cc9e4d1f at news.dial.pipex.com>...
>I have some code which attempts to convert Python arrays (tuples of
>tuples of tuples...) etc. into C arrays with equivalent contents.
>
>The prototype code is shown below.

This doesn't generate legal C.

It also does no bounds checking, so you may end up with a Python int that
doesn't fit into a C char.  (Which is most certainly 1 byte, so why do you
use 4 hex digits to represent it?)

>My only question is, is there some way of doing this without repeating
>the try..except blocks ad-infinitum to handle 3D, 4D arrays etc.

Of course.  This approach you used is in fact very unusual, especially with
the print statements.  You've simply made a special purpose function for
each depth of array.

>I can see there is a pattern here but I can't seem to turn it into a
>loop.  Would a recursive solution do the trick?

The recursive solution is more natural here, I think, but iterative is
possible, too.

The pattern is ', '.join(<elements>), where <elements> is {<arrayORint>}.
The rest is just fluff.

You seem to have gotten hung up on the type declaration.  You can't declare
the type until you know the depth of the array, so generate the array first,
*then* get construct the declaration.

Now for homework, convert the hackish solution below into a recursive
generator. ;)

def seqtobrace(seq, depth=0):
    """Return a comma- and brace-delimited version of seq, and the depth of
seq."""
    depth += 1
    if isinstance(seq[0], (tuple, list)):
        subelem, depths = zip(*[seqtobrace(s, depth) for s in seq])
        delim = ',\n' + ' '*2*depth
        depth = depths[0]
        elements = delim.join(subelem)
    elif isinstance(seq[0], (int, long)):
        elements = ', '.join(map(hex, seq))
    else:
        raise TypeError, "seq must be list or tuple with int or long
leaves."
    return '{ %s }' % elements, depth

def toCarray(seq, name):
    """Return an unsigned char C array declaration of name from seq."""
    assert isinstance(name, basestring)
    if isinstance(seq, (int, long)):
        return 'unsigned char %s = 0x%X;' % (name, seq)
    else:
        array, depth = seqtobrace(seq)
        ad = '[]'*depth
        typedec = 'unsigned char%s %s = \n' % (ad, name)
        return typedec + array + ';'
--
Francis Avila





More information about the Python-list mailing list