0

I am using Calendar and recieve list of lists of lists of tuples from it

calendar.Calendar.yeardays2calendar(calendar.Calendar(), year, 1))

Output is:

[[[[(0, 0), (0, 1), (0, 2), (1, 3), (2, 4), (3, 5), (4, 6)], [(5, 0), (6, 1), (7, 2), (8, 3), (9, 4), (10, 5), (11, 6)], [(12, 0), (13, 1),...

I want to flat map it to simple tuples list saving their order. What is the best way to do map list of any deepness into plain list in python 2.7?

Example of what I want:

[(0, 0), (0, 1), (0, 2), (1, 3), (2, 4), (3, 5), (4, 6),(5, 0), (6, 1), (7, 2), (8, 3), (9, 4), (10, 5), (11, 6), (12, 0), (13, 1)...

Tryied code from other questions - didn't help. Sorry for silly questions, I'm new to python

UPD I tried functions from here python list comprehensions; compressing a list of lists? - didn't help

Community
  • 1
  • 1
maxpovver
  • 1,580
  • 14
  • 25

3 Answers3

4

Python has a function to flatten one nesting level. It goes by the unfortunate name itertools.chain.from_iterable(). If you apply it three times, it will flatten three levels:

import itertools
flatten1 = itertools.chain.from_iterable
flattened_data = flatten1(flatten1(flatten1(your_data)))
for a, b in flattened_data:
    # whatever

More generically, a function that flattens n levels would be

def flatten_n(n, iterable):
    for x in reduce(apply, [itertools.chain.from_iterable] * n, iterable):
        yield x

A function that recursively flattens all lists could look like this:

def flatten_lists(a):
    if isinstance(a, list):
        for b in a:
            for x in flatten_lists(b):
                yield x
    else:
        yield a
Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
3

Try this:

def flatten(x):
    if isinstance(x, list):
        return [a for i in x for a in flatten(i)]
    else:
        return [x]

This answer is similar to this: https://stackoverflow.com/a/2158522/1628832 but checking for the specific list type instead of an iterable.

For optimization, memory efficiency, etc.. you can use yield operation too.

Demo

>>> year = 2015
>>> x = calendar.Calendar.yeardays2calendar(calendar.Calendar(), year, 1)
>>> flatten(x)
[(0, 0), (0, 1), (0, 2), (1, 3), (2, 4), (3, 5), (4, 6), (5, 0), (6, 1), (7, 2), (8, 3), (9, 4), (10, 5), (11, 6), (12, 0), (13, 1), (14, 2), (15, 3), (16, 4), (17, 5), (18, 6), (19, 0), (20, 1), (21, 2), (22, 3), (23, 4), (24, 5), (25, 6), ...]
Community
  • 1
  • 1
karthikr
  • 97,368
  • 26
  • 197
  • 188
0

If you are using Python 2, the following one liner solution will currently work:

import compiler, itertools

lpairs = [[[[(0, 0), (0, 1), (0, 2), (1, 3), (2, 4), (3, 5), (4, 6)], [(5, 0), (6, 1), (7, 2), (8, 3), (9, 4), (10, 5), (11, 6)], [(12, 0), (13, 1)]]]]

print [(x,y) for x,y in itertools.izip(*[iter(compiler.ast.flatten(lpairs))]*2)]

Gives:

[(0, 0), (0, 1), (0, 2), (1, 3), (2, 4), (3, 5), (4, 6), (5, 0), (6, 1), (7, 2), (8, 3), (9, 4), (10, 5), (11, 6), (12, 0), (13, 1)]

Note, the Python compiler module has been deprecated.

Martin Evans
  • 45,791
  • 17
  • 81
  • 97