python-cheatsheet icon indicating copy to clipboard operation
python-cheatsheet copied to clipboard

List flattening does not work properly

Open tweakimp opened this issue 6 years ago • 5 comments
trafficstars

import itertools
nested_list1 = ["s", "r", [32, [32], 3]]
flattened_list1 = list(itertools.chain.from_iterable(nested_list1))
print(flattened_list1)
nested_list2 = [1, [1, 1, 3, [224, 4], []], [], [2, [23]]]
flattened_list2 = list(itertools.chain.from_iterable(nested_list2))
print(flattened_list2)
# RESULT
# ['s', 'r', 32, [32], 3] (flattened_list) <-- not completely flat
# TypeError: 'int' object is not iterable (flattened_list2)  <-- doesnt work at all

I suggest:

from copy import deepcopy
def flatten(nested):
    """Flatten an arbitrarily nested list."""
    nested = deepcopy(nested)
    flat = []
    while nested:
        sublist = nested.pop(0)
        if isinstance(sublist, list):
            nested = sublist + nested
        else:
            flat.append(sublist)
    return flat
list1 = flatten(nested_list1)
list2 = flatten(nested_list2)

print(list1)
print(list2)
# RESULT
# ['s', 'r', 32, 32, 3] (list1)
# [1, 1, 1, 3, 224, 4, 2, 23] (list2)

tweakimp avatar Dec 27 '18 18:12 tweakimp

Thanks. Yes, it's not perfect but it fits on one line, so all I could really do, is remove the example. I mean your function is pretty neat, but it would clutter the List section.

gto76 avatar Dec 27 '18 18:12 gto76

Well you could also put the function somewhere else, not where the original was.

tweakimp avatar Dec 27 '18 18:12 tweakimp

Just saying, but nested = nested[:] should do the same as nested = deepcopy(nested) but without the import. Basically this says the new nested should equal the values of the old nested (copy by value), in contrast to nested = nested which is copy by reference.

s-weigand avatar Mar 26 '19 22:03 s-weigand

Thanks :)

tweakimp avatar Mar 27 '19 05:03 tweakimp

import itertools
nested_list1 = ["s", "r", [32, [32], 3]]
flattened_list1 = list(itertools.chain.from_iterable(nested_list1))
print(flattened_list1)
nested_list2 = [1, [1, 1, 3, [224, 4], []], [], [2, [23]]]
flattened_list2 = list(itertools.chain.from_iterable(nested_list2))
print(flattened_list2)
# RESULT
# ['s', 'r', 32, [32], 3] (flattened_list) <-- not completely flat
# TypeError: 'int' object is not iterable (flattened_list2)  <-- doesnt work at all

I suggest:

import itertools

def flatten_list(nested_list):
    flattened_list = []
    for item in nested_list:
        if isinstance(item, list):
            flattened_list.extend(flatten_list(item))
        else:
            flattened_list.append(item)
    return flattened_list

bharathkanchoju avatar Jan 16 '24 09:01 bharathkanchoju

I changed 'flattened_list' to 'flatter_list'. This issue should have been closed long ago. Thanks for the input but there's no space left (except for a few additional lines in Coroutines and Plotly).

gto76 avatar Jan 16 '24 21:01 gto76