HappyPy
HappyPy

Reputation: 10697

create sublists within sublists in python

I'd like to create a series of sublists within a sublist:

original = range(1,13)

I read another post that provided a solution to create sublists within a list:

>>> [original[i:i+2] for i in range(0,len(original),2)]
>>> [[1,2], [3,4], [5,6], [7,8], [9,10], [11,12]]

But how can I achieve this result?

[ [[1,2],[3,4]], [[5,6],[7,8]], [[9,10],[11,12]] ] 

Upvotes: 0

Views: 127

Answers (3)

ely
ely

Reputation: 77404

You can define your sublisting action as a function and apply it twice. This is probably inefficient since it will construct intermediate lists before constructing ones with the finest level of sublisting. But, is is easier to read since you're already familiar with the first step given that you used it when asking this question.

def nest_in_pairs(original):
    return [original[i:i+2] for i in range(0,len(original),2)]

print nest_in_pairs(nest_in_pairs(original))

A more efficient way to do it would be to create a generator that yields a list of up to two items from the front of the list. Then chain them.

from types import GeneratorType

def yield_next_two(seq):
    if not isinstance(seq, GeneratorType):
        for i in range(0, len(seq), 2):
            yield seq[i:i+2]
    else:
        while True:
            item1 = next(seq)
            try:
                item2 = next(seq)
                yield [item1, item2]
            except StopIteration:
                yield [item1]

pair_generator = yield_next_two(original)

quad_generator = yield_next_two(yield_next_two(original))

next(pair_generator)

next(quad_generator)

and you can call list on pair_generator or quad_generator to get the whole set of contents.

Here's an example of playing with this after pasting the above code into an IPython session:

In [40]: quad_generator = yield_next_two(yield_next_two(original))

In [41]: list(quad_generator)
Out[41]: [[[1, 2], [3, 4]], [[5, 6], [7, 8]], [[9, 10], [11, 12]]]

In [42]: nearly_eights_generator = yield_next_two(yield_next_two(yield_next_two(original)))

In [43]: list(nearly_eights_generator)
Out[43]: [[[[1, 2], [3, 4]], [[5, 6], [7, 8]]], [[[9, 10], [11, 12]]]]

Upvotes: 4

Fred S
Fred S

Reputation: 995

You could run the same code twice:

>>> original = range(1,13)
>>> [original[i:i+2] for i in range(0,len(original),2)]
output --> [[1,2], [3,4], [5,6], [7,8], [9,10], [11,12]]

>>> original = range(1,13)
>>> original = [original[i:i+2] for i in range(0,len(original),2)]
>>> [original[i:i+2] for i in range(0,len(original),2)]
output --> [[[1, 2], [3, 4]], [[5, 6], [7, 8]], [[9, 10], [11, 12]]]

Upvotes: -1

corn3lius
corn3lius

Reputation: 4985

orig = range(1,13)
def squeeze( original ): 
    return [original[i:i+2] for i in range(0,len(original),2)]
print ( squeeze(squeeze(orig)) )

Upvotes: 2

Related Questions