Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flatten multi dimensional array in python 3

I have a list of numbers: testList = [1, [1], [12], 2, 3]

I want it to become: flatList = [1, 1, 12, 2, 3]

Using a typical list comprehension such as below is not working.

flatList = [val for sublist in testList for val in sublist]
TypeError: 'int' object is not iterable

I suspected it is because the un-nested items are being treated as iterable sublists, so I tried this:

flatList = [val if isinstance(sublist, int) == False else val for sublist in testlist for val in sublist]

But I am unclear on the syntax, or if there is some better way to do this. Trying to remove val from the else clause means val is undefined. As is, it still gives me the same TypeError.

The code below does work for me, but I am interested to see if it can be done in list comprehension style, and people's opinions on that.

for sublist in testlist:
    if type(sublist) == int:
        flat.append(sublist)
    else:
        for val in sublist:
            flat.append(val)
print(flat)

>>>[1, 1, 12, 2, 3]
like image 679
CameronAtkinson Avatar asked Nov 22 '17 10:11

CameronAtkinson


People also ask

How do you flatten a multidimensional array?

To flatten an array means to reduce the dimensionality of an array. In simpler terms, it means reducing a multidimensional array to a specific dimension. let arr = [[1, 2],[3, 4],[5, 6, 7, 8, 9],[10, 11, 12]]; and we need to return a new flat array with all the elements of the nested arrays in their original order.

How do you flatten a 3d matrix in Python?

By using ndarray. flatten() function we can flatten a matrix to one dimension in python. order:'C' means to flatten in row-major. 'F' means to flatten in column-major.

What is the use of flatten in Python?

flatten() function. The flatten() function is used to get a copy of an given array collapsed into one dimension.


2 Answers

Since you're using Python 3, you can take advantage of yield from with a recursive function. It has been introduced in Python 3.3.

As a bonus, you can flatten arbitrary nested lists, tuples, sets or ranges:

test_list = [1, [1], [12, 'test', set([3, 4, 5])], 2, 3, ('hello', 'world'), [range(3)]]

def flatten(something):
    if isinstance(something, (list, tuple, set, range)):
        for sub in something:
            yield from flatten(sub)
    else:
        yield something


print(list(flatten(test_list)))
# [1, 1, 12, 'test', 3, 4, 5, 2, 3, 'hello', 'world', 0, 1, 2]
print(list(flatten('Not a list')))
# ['Not a list']
print(list(flatten(range(10))))
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Here's another example with a debug line:

def flatten(something, level=0):
    print("%sCalling flatten with %r" % ('  ' * level, something))
    if isinstance(something, (list, tuple, set, range)):
        for sub in something:
            yield from flatten(sub, level+1)
    else:
        yield something

list(flatten([1, [2, 3], 4]))
#Calling flatten with [1, [2, 3], 4]
#  Calling flatten with 1
#  Calling flatten with [2, 3]
#    Calling flatten with 2
#    Calling flatten with 3
#  Calling flatten with 4
like image 194
Eric Duminil Avatar answered Oct 03 '22 23:10

Eric Duminil


If the sublists always contain only one item then

flatList = [item[0] if isinstance(item, list) else item for item in testList]
like image 20
kaidokuuppa Avatar answered Oct 04 '22 00:10

kaidokuuppa