1

I have a nd python array (not a numpy array), and it looks something like this

[[[1,2,3], [4,5,6]]] 

I'd like to be able to remove all the unnecessary arrays so that I end up with

[[1,2,3], [4,5,6]]

And I wrote a function to handle this

def remove_unnecessary(array:list) -> list:
    while True:
        try:
            array = *array
        except TypeError:
            return array

However this doesn't work, and that's mainly due to my lack of knowledge on using starred expressions to unwrap lists. Does anyone have an idea on how I could fix this or how I could better use * in this function?

Aguy
  • 169
  • 11
  • _I have a nd python array_ ... _`array:list`_ ? Please be more specific about the operation you wish to perform. For example, what happens if the input is `[[[1, 2, 3]], 4, 5]` ? – AMC Feb 08 '20 at 17:42
  • "nd python array" no such thing exists. Python *list objects* do *not have dimensions*, they are heterogenous sequences of Python objects. – juanpa.arrivillaga Feb 08 '20 at 19:18
  • @AMC it should be assumed that all sizes in each dimension of the python list would be the same. So [[[1,2,3]], 4, 5] would not be allowed. – Aguy Feb 08 '20 at 20:19
  • @juanpa.arrivillaga I know that python lists, regardless of "dimension", are stored as as a single sequence of values. However wouldn't you agree that when representing a "nd python list" its much easier to refer to it as such? – Aguy Feb 08 '20 at 20:21
  • @juanpa.arrivillaga Also you have marked my question as a duplicate, however I'm not looking to completely flatten my python list. I'm looking to remove any unnecessary "dimensions" such that [[[1,2,3], [4,5,6]]] would become [[1,2,3], [4,5,6]] and not [1,2,3,4,5,6]. I should have provided a better example and have since updated my question. – Aguy Feb 08 '20 at 20:26
  • 1
    @Aguy can't answer because closed, but your looking for `array, = array` (However, it would probably be clearer to go for `while len(array) == 1: array = array[0]` wrapped in the `try`/`except TypeError`) – Artyer Feb 08 '20 at 21:17
  • @Artyer this is a nice simple and clean way to solve the problem. Thanks for your help. Also the question has now been reopened. – Aguy Feb 08 '20 at 21:48

3 Answers3

2

You can just iterate until you don't reach the inner elements. Example:

>>> def remove_unnecessary(l):
...     while len(l) == 1 and isinstance(l[0], list):
...             l=l[0]
...     return l
... 
>>> remove_unnecessary([[[1,2,3], [4,5,6]]])
[[1, 2, 3], [4, 5, 6]]
>>> remove_unnecessary([[[[[1,2,3], [4,5,6]]]]])
[[1, 2, 3], [4, 5, 6]]
>>> remove_unnecessary([1])
[1]
>>> remove_unnecessary([[1]])
[1]
abc
  • 11,579
  • 2
  • 26
  • 51
1

You can try this:

>>> import numpy as np
>>> l = [[[1,2,3]]]
>>> list(np.array(l).flatten())
[1, 2, 3]
schlodinger
  • 537
  • 3
  • 14
  • That works, but I'd rather not use numpy in this python project. I'd like to use pure python and not rely on any dependencies. I should have mentioned that I'm trying to create a tensor math library using cython to improve speed and performance. – Aguy Feb 08 '20 at 17:11
1

I wrote a recursive function for this. Let me know if this does the job for you.

Code

def list_flatten(example: list) -> list:
    try:
        if example:
            if len(example) > 1:
                return example
            elif len(example) == 1 and len(example[0]) != 1:
                return [elem for element in example for elem in element]
            elif len(example) == 1 and len(example[0]) == 1:
                return list_flatten(example[0])
        else:
            return "List empty"
    except TypeError:
        return example

Sample Inputs

example_list = [[[[[1,2,3], [4,5,6], [1]]]]]
example_list_test = [1, 3, 4, 5, 6, 7]
empty_example = []

Outputs

list_flatten(example_list) gives:
[[1, 2, 3], [4, 5, 6], [1]]

list_flatten(example_list_test) gives:
[1, 3, 4, 5, 6, 7]

list_flatten(empty_example) gives:
'List empty'
Rahul P
  • 2,493
  • 2
  • 17
  • 31
  • 1
    Thanks for your answer! it does exactly what I need it to and it doesn't completely flatten the list which is great. I also tried using a recursive function at first but it don't work. However the code does seem a little clunky compared to another way I have seen of solving this problem. – Aguy Feb 08 '20 at 22:10
  • 1
    @Aguy you are welcome. And agreed, the accepted solution is better. I can't believe I didn't think of it either. – Rahul P Feb 08 '20 at 22:17