3

This question differs from Converting list of lists / nested lists to list of lists without nesting (this yields a very specific set of responses that do not address my situation) and also from the many "flatten list of lists to list" answers out there.

I want to take a list of lists, some of which are in turn lists of lists and "flatten" to a list of lists (not just a list!).

As a concrete example, I want to go from this:

my_list_of_lists = [[1, 2, 3], [[9, 10], [8, 9, 10], [3, 4, 6]], [11, 12, 13]]

to this

target_list_of_lists = [[1, 2, 3], [9, 10], [8, 9, 10], [3, 4, 6], [11, 12, 13]]

(In a visual sense, I want to turn all [[ and ]] inside the outer list into [ and ] respectively.)

Akaisteph7
  • 5,034
  • 2
  • 20
  • 43
Ian Gow
  • 3,098
  • 1
  • 25
  • 31
  • 1
    I don't think the proposed duplicate is correct, as this question doesn't want to fully flatten the list, just remove some layers of the nesting, while keeping others. – Blckknght Jul 21 '19 at 23:42

1 Answers1

4

Here's one way to do it:

def flatten(lst, dh=None):
    # Added so user does not need to pass output list
    if (dh is None):  
        dh = []
    for elem in lst:
        # Will not try to iterate through empty lists
        if elem and (isinstance(elem[0], list)):  
            flatten(elem, dh)
        else:
            dh.append(elem)
    return dh

my_list_of_lists = [[1, 2, 3], [[9, 10], [8, 9, 10], [3, 4, 6]], [11, 12, 13]]
target_list_of_lists = flatten(my_list_of_lists)
print(target_list_of_lists)

Output:

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

This will work for lists of any length and any depth.

Akaisteph7
  • 5,034
  • 2
  • 20
  • 43
  • Maybe cleaner to add a default: `def flatten(lst, dh = None): #... dh = [] if dh is None else dh` and a `return dh` at the end so that the final user doesn't *have* to set up the output buffer? – Linuxios Jul 21 '19 at 23:55
  • Careful -- you need the ` = None` and the conditional so you start a fresh list with each top level invocation. Otherwise: `def test(a = []): a.append(45); return a; test() #=> [45]; test() #=> [45, 45]` – Linuxios Jul 22 '19 at 00:39
  • 1
    :) (We all do... I spent longer than I'd like to admit on one of those the other day...) – Linuxios Jul 22 '19 at 00:44
  • 1
    Note that my actual list had `[]` in the list of lists (for example, `my_list_of_lists = [[1, 2, 3], [], [[9, 10], [], [8, 9, 10], [3, 4, 6]], [11, 12, 13]]`). This broke the solution, but changing the condition to `if elem and (isinstance(elem[0], list)):` made it work. – Ian Gow Jul 22 '19 at 01:33