Python Forum
Making list empty after return in function
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Making list empty after return in function
#1
Hello, I have one trouble in my program I´m currently working on. I need to make a function, which flatten a list whom items can contain lists again, into a one simple list. Function gets a list as a parameter and I need to return new flattened list without changing the main one, using recursion.

This is my current attempt:

result = []

def flatten(nested_list):
    for i in nested_list:
        if type(i) != list:
            result.append(i)
        else:
            flatten(i)
    return result
The problem here is, as soon as I want to run this function again, it remembers the last result, what means that it appends everything at the end. But I want to make a new result, containing just a simple list of current nested one. How can I remove last result when calling function again?

Thanks.
Reply
#2
There are different solutions, but I prefer to use a closure and a helper function like so
def flatten(to_flatten):
    result = []

    def helper(nested_list):
        for i in nested_list:
            if type(i) != list:
                result.append(i)
            else:
                helper(i)
        return result

    return helper(to_flatten)
Alternatively, you could have a second parameter which defaults to None, and you have have logic which creates the result variable when that parameter is None and then provide it for the recursive calls. I prefer the method I've coded here because it does not change the interface given to clients of the code, who might accidentally provide a second parameter (or who might notice it and wonder).
Reply
#3
Thanks for your help. But, I fear that the first solution you described is not entirely appropriate for my program. There should stay 1 function, no more.
And about second solution - can you please describe it a bit more, it´s not very clear for me, what exactly you mean.
Reply
#4
If you never want to save the result for the next call, just put result = [] as the first statement inside the function, rather than outside the function.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#5
But when I make it like this:

def flatten(nested_list):
    result = []
    for i in nested_list:
        if type(i) != list:
            result.append(i)
        else:
            flatten(i)
    return result
it clears the list every time when calling a recursion. So from input flatten([0,1,2,[3,4]]) I get output just [0,1,2]
Reply
#6
If you have only a nested list, not a deep nested list, you can use itertools.chain.from_iterable


from itertools import chain


flatten = chain.from_iterable
nested = [('a', 'b', 'r', 'a'),('c', 'a', 'd', 'a', 'b', 'r', 'a')]
result = list(flatten(nested))

print(result)
Output:
['a', 'b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a']
chain.from_iterable returns an iterator. You have to consume this iterator to result by result.
If you always want to have a list as result, you can make a function for it.

from itertools import chain


def flatten_to_list(iterable):
    return list(chain.from_iterable(iterable))


nested = [('a', 'b', 'r', 'a'),('c', 'a', 'd', 'a', 'b', 'r', 'a')]

print(flatten_to_list(nested))
Output:
['a', 'b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a']
Reference from Python documentation: itertools itertools-recipes

Do you like it? You should read the whole description of this module. It's very powerful. Mostly all parts of Python language have implemented iteration. The benefit is also, that you can work with "big data" or data-streams. The iterator protocol allows this. The function flatten_to_list removes this ability, because the list is constructed in memory until the iteration ends. It's not possible with infinite streams, except if you use itertools.islice(iterable, start, end).

In addition, you get back, what you want. If you want to have a set, then use set(chain.from_iterable(nested_something)).
This can be done also with tuple, list, dict.fromkeys and other types which consumes iterables.


Bonus: You can do it also with str.join

result1 = str.join('-', flatten(nested))
# or
result2 = '-'.join(flatten(nested))

print(result1)
print(result2)
Output:
a-b-r-a-c-a-d-a-b-r-a a-b-r-a-c-a-d-a-b-r-a
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#7
Sorry, missed the recursion. My bad.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#8
This should do it:

def flatten(nested_list):
    result = []
    for i in nested_list:
        if type(i) != list:
            result.append(i)
        else:
            result.extend(flatten(i))
    return result
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#9
I made a while ago a function to flatten deep nested structures. I wrote it, but I still need 2 minutes to watch this code, to understand what I have done :-D

https://stackoverflow.com/questions/2158...1#45213701

There is still an big error inside. I do not pay attention about bytearrays.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#10
Thanks to both of you. I will check how do your codes sit into my program.. :)
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  How do I calculate a ratio from 2 numbers and return an equivalent list of about 1000 Pleiades 8 15,719 Jan-05-2024, 08:30 PM
Last Post: sgrey
  Code with empty list not executing adeana 9 3,753 Dec-11-2023, 08:27 AM
Last Post: buran
  nested function return MHGhonaim 2 619 Oct-02-2023, 09:21 AM
Last Post: deanhystad
  return next item each time a function is executed User3000 19 2,306 Aug-06-2023, 02:29 PM
Last Post: deanhystad
  function return boolean based on GPIO pin reading caslor 2 1,192 Feb-04-2023, 12:30 PM
Last Post: caslor
  Making a function more efficient CatorCanulis 9 1,863 Oct-06-2022, 07:47 AM
Last Post: DPaul
  set.difference of two list gives empty result wardancer84 4 1,513 Jun-14-2022, 01:36 PM
Last Post: wardancer84
  Showing an empty chart, then input data via function kgall89 0 984 Jun-02-2022, 01:53 AM
Last Post: kgall89
  displaying empty list vlearner 5 1,685 Jan-19-2022, 09:12 AM
Last Post: perfringo
  Remove empty keys in a python list python_student 7 3,051 Jan-12-2022, 10:23 PM
Last Post: python_student

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020