Python Forum
flattening a list with some elements being lists
Thread Rating:
  • 1 Vote(s) - 3 Average
  • 1
  • 2
  • 3
  • 4
  • 5
flattening a list with some elements being lists
#1
a list might be like [[1,2,3],4,[5,6,7,8],[9]] and i want to flatten it to [1,2,3,4,5,6,7,8,9]. how easy is this to do if it is only 2 levels like that? what if it goes even deeper like [[1,2,3],4,[5,[[6,7],8]],[9]]. is it any easier as a list than any type of iterator? would this be any easier if the iterators were ranges?
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#2
There is a generator function here. Look at it.
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#3
looking for something simpler. i think i am getting close.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#4
This could be simpler and should work:

>>> m = [[1,2,3],4,[5,[[6,7],8]],[9]]
>>> def flatten(lst):
...     for item in lst:
...         try:
...             yield from flatten(item)
...         except TypeError:
...             yield item
...
>>> list(flatten(m))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
I should mention that if list contains string(s) function fails miserably (maximum recursion depth exceeded)
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#5
you could test for list type somewhere to avoid trying to iterate a string.

* Skaperen thinks that code would be a great example for the language reference

that code gave me hints, but i wanted something that would also work in Python2, so no yield from. i came up with this code, which works without being a generator at all. i created it as a code file with test code, instead of an interactive session, since i wanted to keep it.

flatten.py:
def flatten(*a):
    if len(a)==1:
        l=[]
        flatten(a[0],l)
        return l
    if isinstance(a[0],list):
        for e in a[0]:
            flatten(e,a[1])
        return
    a[1].append(a[0])
    return

x=[[1,2,3],4,[5,[[6,7],8]],[9]]
print(repr(x))
y=flatten(x)
print(repr(y))
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#6
(Aug-06-2018, 06:03 AM)perfringo Wrote: I should mention that if list contains string(s) function fails miserably (maximum recursion depth exceeded)
I had this issue with strings. You can see the link in my prev. post.
I like the way you use try/except. I didn't even think to catch an exception.
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#7
Let's bend our minds little further Smile

This should be compatible with Python 2 and handle strings as well:

def flatten(lst):
    def _flatten(lst, result):    
        if type(lst) is not list:
            result.append(lst)
        else:
            for item in lst:
                result = result + flatten(item)
        return result
    return _flatten(lst, [])
This will produce:
>>> n = [[1, 2, 3], [[4]], [5], [['spam','ham','bacon'] , [['foo','bar','baz']], ['x','y','z']], 6]
>>> flatten(n)
[1, 2, 3, 4, 5, 'spam', 'ham', 'bacon', 'foo', 'bar', 'baz', 'x', 'y', 'z', 6]
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#8
def flatten(lst):
    result = []
    for item in lst:
        if isinstance(item, (list, tuple)): # You may add more container types if needed
            result.extend(flatten(item))
        else:
            result.append(item)
    return result
    
n = [[1, 2, 3], [[4]], [5], [['spam','ham','bacon'] , [['foo','bar','baz']], ('x','y','z')], 6]
print flatten(n)
Output:
[1, 2, 3, 4, 5, 'spam', 'ham', 'bacon', 'foo', 'bar', 'baz', 'x', 'y', 'z', 6]
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#9
(Aug-06-2018, 10:18 AM)buran Wrote:
def flatten(lst):
    result = []
    for item in lst:
        if isinstance(item, (list, tuple)): # You may add more container types if needed
            result.extend(flatten(item))
        else:
            result.append(item)
    return result
    

This is the reason I like Python - smart people (like buran) can achieve desired results with minimal and very readable piece of code. I have lot of work to do in smart part Smile
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#10
Using a generic function to dispatch according to the argument's type
>>> import functools
>>> @functools.singledispatch
... def flatten(x):
...     return [x]
... 
>>> @flatten.register(list)
... @flatten.register(tuple)
... def _(x):
...     return [z for y in x for z in flatten(y)]
... 
>>> a = [[1, 2, 3], [[4]], [5], [['spam','ham','bacon'] , [['foo','bar','baz']], ('x','y','z')], 6]
>>> flatten(a)
[1, 2, 3, 4, 5, 'spam', 'ham', 'bacon', 'foo', 'bar', 'baz', 'x', 'y', 'z', 6]
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  unable to remove all elements from list based on a condition sg_python 3 373 Jan-27-2024, 04:03 PM
Last Post: deanhystad
Question mypy unable to analyse types of tuple elements in a list comprehension tomciodev 1 427 Oct-17-2023, 09:46 AM
Last Post: tomciodev
  List all possibilities of a nested-list by flattened lists sparkt 1 878 Feb-23-2023, 02:21 PM
Last Post: sparkt
  Checking if a string contains all or any elements of a list k1llcod3 1 1,023 Jan-29-2023, 04:34 AM
Last Post: deanhystad
  user input values into list of lists tauros73 3 1,024 Dec-29-2022, 05:54 PM
Last Post: deanhystad
  returning a List of Lists nafshar 3 1,014 Oct-28-2022, 06:28 PM
Last Post: deanhystad
  Creating list of lists, with objects from lists sgrinderud 7 1,561 Oct-01-2022, 07:15 PM
Last Post: Skaperen
  How to change the datatype of list elements? mHosseinDS86 9 1,899 Aug-24-2022, 05:26 PM
Last Post: deanhystad
  ValueError: Length mismatch: Expected axis has 8 elements, new values have 1 elements ilknurg 1 5,013 May-17-2022, 11:38 AM
Last Post: Larz60+
  How to efficiently average same entries of lists in a list xquad 5 2,070 Dec-17-2021, 04:44 PM
Last Post: xquad

Forum Jump:

User Panel Messages

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