idiomatic repeating group file format parsing
<pre><code>repeating_group_field = ['a', 'b', 'c']


ddata = ['l', 'm', 'n', 2, 'a', 'b', 'a', 'c', 'b', 'g', 'h', 2, 'c', 'c', 'l', 2, 'b', 'b']

# output = ['l', 'm', 'n', [['a', 'b'],['a', 'c', 'b']], 'g', 'h', [['c'], ['c']], 'l', 2, [[b], [b]]]


def outer(it):
    last = {'value': None}

    def rgroup(i, it):

        def group(delim, it):
            yield delim
            for i in it:
                if i in repeating_group_field and i is not delim:
                    yield i
                else:
                    last['value'] = i
                    return
            last['value'] = None
        delim = it.next()
        for x in range(i):
            yield [y for y in group(delim, it)]

    for i in it:
        if type(i) is int:
            yield [x for x in rgroup(i, it)]
            if last['value']:
                yield last['value']
        else:
            yield i

it = iter(ddata)
result = [z for z in outer(it)]

print result



def flatter(dataset):
    iterator = iter(dataset)
    for datum in iterator:
        if type(datum) is int:
            acc = []
            delim = iterator.next()
            for n in range(datum):
                subacc = []
                subacc.append(delim)
                while True:
                    try:
                        repeating_group_element = iterator.next()
                        if repeating_group_element not in repeating_group_field:
                            acc.append(subacc)
                            yield acc
                            yield repeating_group_element
                            break
                        if repeating_group_element != delim:
                            subacc.append(repeating_group_element)
                        else:
                            acc.append(subacc)
                            break
                    except StopIteration:
                        acc.append(subacc)
                        yield acc
                        return
        else:
            yield datum

g = [y for y in flatter(ddata)]

print g
</code></pre>

<p>I've presented two working algorithms above to convert the input data to the desired internal data structure. The rules of the input data are as follows: an int in the input indicates a repeating group, the first element following the repeating group indicator is the repeating group delimiter. The appearance of the delimiter in the input data indicates the start of the next instance of the repeating group. The number of elements in the repeating group is not specified in the repeating group header. The presence of a non-repeating group field in the input stream indicates the end of the repeating group. Validation of the input is not required. </p>

<p>The first implementation uses nested functions and no accumulators. The second implementation is more flat and uses accumulators. I'm just wondering if there is a more idiomatic way to implement this algorithm in Python.  </p>

<p>I doubt there is something clear and simple for such a sophisticated data re-packing procedure.</p>

<p>I did a version of this from scratch, but in no way it looks beautiful (though it looks simplier to me).</p>

<pre><code>def chew_data(data):
    def check_type(char):
        nonlocal inside_group
        if type(char) is int:
            inside_group = True
        else:
            inside_group = False
            return char

    inside_group = False
    group_delimiter = ''
    group_result = []
    subgroup_result = []
    for c in data:
        if not inside_group:
            if check_type(c):
                yield c
        else:
            if c == group_delimiter:
                group_result.append(subgroup_result)
                subgroup_result = []
            if not group_delimiter:
                group_delimiter = c
            if c in repeating_group_field:
                subgroup_result.append(c)
            else:
                group_result.append(subgroup_result)
                subgroup_result = []
                yield group_result
                group_result = []
                group_delimiter = ''
                if check_type(c):
                    yield c
    group_result.append(subgroup_result)
    yield group_result
</code></pre>

python