# [Chicago] Resolving lists within lists within lists within .....

Lewit, Douglas d-lewit at neiu.edu
Thu Feb 18 15:01:55 EST 2016

```Aaron,

That is really cool!  I didn't try the code yet, but just traced through
the logic of it.  I really like it.  I'm guessing that with your second
example you would need to use something like:

try:
print( next(y) )
except StopIteration:
pass

because eventually "next" just "runs out" and then Python raises its
StopIteration Error.  ( Although I'm kind of wondering if there's a way to
make "next" circular so that when it "runs out" it just goes right back to
the original yield statement.  I remember doing that once and it worked,
but.... I kind of forgot how to do that. )

Aaron, you mentioned that recursion is not one of Python's strong points.
Why is that the case and what could the developers do to enhance Python's
capabilities for implementing recursive algorithms.  Thanks for sharing.

Best,

Douglas.

On Thu, Feb 18, 2016 at 1:43 PM, Aaron Elmquist <elmq0022 at umn.edu> wrote:

> Douglas,
>
> Here's one more version for you and the rest of the list. It's based on
> Brad's code.  I will let you think about why this version might be better
> or worse.  Also, recursion is great.  It's just too bad it's not one of
> python's strong points.
>
> def flatten(lst):
>     for item1 in lst:
>         if hasattr(item1, '__iter__'):
>             for item2 in flatten(item1):
>                 yield item2
>         else:
>             yield item1
>
> print([x for x in flatten([1, [2,3,[4,5,6,[7,8,9]]]]) if x%2 == 1])
>
> y = flatten([1, [2,3,[4,5,6,[7,8,9]]]])
>
> print(next(y))
> print(next(y))
> print(next(y))
> .
> .
> .
>
>
>
> On Wed, Feb 17, 2016 at 11:21 PM, Lewit, Douglas <d-lewit at neiu.edu> wrote:
>
>> Hey Massimo,
>>
>> That one-liner is so cool!  Thanks!  Simple and gets the job done.
>> Thanks for sharing.
>>
>> On Wed, Feb 17, 2016 at 9:48 PM, DiPierro, Massimo <
>> MDiPierro at cs.depaul.edu> wrote:
>>
>>> here is a one liner:
>>>
>>> def flatten(x):
>>>     return [z for y in x for z in flatten(y)] if isinstance(x,list) else
>>> [x]
>>>
>>>
>>>
>>> On Feb 17, 2016, at 9:30 PM, Lewit, Douglas <d-lewit at neiu.edu<mailto:
>>> d-lewit at neiu.edu>> wrote:
>>>
>>> Hi Mark,
>>>
>>> Thanks for those links.  Yes, Linus Torvalds is quite a legend in his
>>> own time.  I'll be content to become 1% of the programmer that he is!   :-)
>>>
>>> My original question was simple, "Does Python have a builtin function
>>> for flattening lists?"  It was a very simple question that provoked a very
>>> strange and hostile thread!  I'm not sure why that is.  Anyhow, someone
>>> mentioned itertools.chain( ).  Can someone provide a concrete example of
>>> how that function works?  Or is that question inappropriate?  And please,
>>> type of reply, okay?  Thank you.
>>>
>>>
>>>
>>> On Wed, Feb 17, 2016 at 2:52 PM, Mark Graves <mgraves87 at gmail.com
>>> <mailto:mgraves87 at gmail.com>> wrote:
>>> I don't mean to be argumentative or add to this discussion in a negative
>>> way.
>>>
>>> Could we have a little direction from a higher up around the code of
>>> conduct here?  For reference, this is the only one I found:
>>>
>>> http://www.chipy.org/pages/conduct/
>>>
>>> I am in support of Doug asking his questions and agree with Adam on
>>> this. I've met Doug, and sometimes his humor is lost on people through the
>>> mailing list.  If you are bothered, you can always create an email filter.
>>>
>>> FWIW, imagine if the developer at the top of this list had been
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> On Wed, Feb 17, 2016 at 11:50 AM, Mike Tamillow <
>>> mikaeltamillow96 at gmail.com<mailto:mikaeltamillow96 at gmail.com>> wrote:
>>> Yeah, but I generally agree that this list shouldn't be used for help
>>> with personal programming problems. There is a website called stack
>>> overflow as well as much documentation that can be consulted for this.
>>>
>>> What I like best is when messages come out exposing me to some open
>>> source tool I have yet to hear about that may be useful.
>>>
>>> I'm sure there's other great discussions but I don't think code by email
>>> is quite a good thing to send out to hundreds of people.
>>>
>>> Sent from my iPhone
>>>
>>>
>>> Hey everyone,
>>>
>>> Please remember that intentions can be hard to judge on the mailing
>>> list. I've met Douglas in person and he's a nice guy. Please don't assign
>>> motives just because there are issues communicating.
>>>
>>>
>>>
>>> On Wed, Feb 17, 2016 at 10:02 AM, Chris Foresman <foresmac at gmail.com
>>> <mailto:foresmac at gmail.com>> wrote:
>>> Honestly, Douglas, you come to the list all the time asking for help or
>>> opinions and then you precede to generally be a jerk to people that respond
>>> to you. The fact is your solution is sloppy, confusing, and doesn’t work at
>>> least as far as you originally explained it was supposed to work. Brad
>>> pointed all this out and suggested a vastly better alternative, and did so
>>> in an extremely polite way. Your response was just acerbic and doltish.
>>> Please consider either accepting constructive criticism with humility or
>>> just stop asking for help.
>>>
>>>
>>> Regards,
>>> Chris Foresman
>>> chris at chrisforesman.com<mailto:chris at chrisforesman.com>
>>>
>>>
>>>
>>> On Feb 16, 2016, at 10:44 PM, Lewit, Douglas <d-lewit at neiu.edu<mailto:
>>> d-lewit at neiu.edu>> wrote:
>>>
>>> Use flattenAgain.... which calls flatten repeatedly until there's no
>>> change in the list.  You have to use BOTH functions!
>>>
>>> Sarcasm?  What's that?
>>>
>>>
>>> On Tue, Feb 16, 2016 at 10:37 PM, Brad Martsberger <
>>> Douglas, I don't know if that was supposed to be sarcastic or what.
>>>
>>> In fact, your code does not work.
>>>
>>> >>> flatten([[[1, 2], 3], 4])
>>> [[1, 2], 3, 4]
>>>
>>> Looks like it fails to fully flatten the list.
>>>
>>> I assumed from your original email you were interested in other
>>> approaches, so I gave one that looks to me like it's much less complex (no
>>> need for try/except, no need for indexing, 1 recursive call instead of 3).
>>> Less complex code is usually easier to reason about and less prone to bugs.
>>>
>>> In purely functional languages there is no for loop, so if you want to
>>> iterate over a list, you have to do it with recursive function calls.
>>> Recursion stops when there's nothing left in the list, so the base case is
>>> the empty list. Since iterating over a list is so common in programming, it
>>> can start to feel like this is the way recursion and lists go together.
>>>
>>> But a good rule of thumb is only good if it doesn't trip you up when you
>>> com across an exception to the rule. In the problem of flattening a list,
>>> the recursion is down the depth of nesting, not across the list. In this
>>> case, you can stop flattening when you hit a non-list object, so that's
>>>
>>>
>>> On Tue, Feb 16, 2016 at 2:50 PM, Lewit, Douglas <d-lewit at neiu.edu
>>> <mailto:d-lewit at neiu.edu>> wrote:
>>> Whether it looks pythonic or not Joshua, it works!  Try it before you
>>> criticize it!!!   ;-)   In implementing recursive functions on lists, one
>>> of the base cases is almost always whether the list is empty or not.  A
>>> little lesson I learned from studying lists in Haskell and Ocaml.  Hard
>>> languages for sure, but they made me a stronger programmer when it comes to
>>> the dreaded "R" ( Recursion ).   ;-)
>>>
>>>
>>> On Tue, Feb 16, 2016 at 1:13 PM, Brad Martsberger <
>>> > you can get almost there with itertools.chain.from_iterable
>>>
>>> It's tempting, but it fails in a lot of ways. It successfully flattens a
>>> list of lists, but doesn't go any deeper than that and fails completely on
>>> a list composed of some lists and some non-list objects. You can also get
>>> the same behavior out of a list comprehension.
>>>
>>> Douglas, you have written a recursive function, but I think you've
>>> missed on what the base case is. The base case is not whether or not you've
>>> been passed an empty list, but rather whether an element is a list or not
>>> (if it's not, you don't need any further flattening. Also, all those
>>> indices don't look very pythonic.
>>>
>>> Here is a recursive flatten function that will handle any depth and
>>> mixed depths at different elements (no indexing required)
>>>
>>> def flatten(lst):
>>>     new_list = []
>>>     for element in lst:
>>>         if isinstance(element, list):
>>>             new_list.extend(flatten(element))
>>>         else:
>>>             # This is the base case where the recursion ends
>>>             new_list.append(element)
>>>
>>>     return new_list
>>>
>>> >>> flatten([[1, 1.1], 2, 3, [4, 5, [6, 7, 8]]])
>>> [1, 1.1, 2, 3, 4, 5, 6, 7, 8]
>>>
>>> On Mon, Feb 15, 2016 at 9:09 PM, Joshua Herman <zitterbewegung at gmail.com
>>> <mailto:zitterbewegung at gmail.com>> wrote:
>>> The idea of flattening a object or datatype is a functional programming
>>> technique and not just a part of Ruby and Mathematica According to this
>>> answer on the programming stack exchange there is no method / function that
>>> implements flatten for build in Python functions but you can get almost
>>> there with itertools.chain.from_iterable . See
>>> http://programmers.stackexchange.com/questions/254279/why-doesnt-python-have-a-flatten-function-for-lists
>>> .
>>> On Feb 15, 2016, at 4:12 PM, Lewit, Douglas <d-lewit at neiu.edu<mailto:
>>> d-lewit at neiu.edu>> wrote:
>>>
>>> Hi everyone,
>>>
>>> Well it's President's Day and I've got the day off!  Hooray!!!  Finally
>>> some time to just relax and mess around.  So I'm at my computer playing
>>> around with Python and wondering how to resolve the issue of multiple lists
>>> embedded within other lists.  I came up with two functions that I think
>>> solve the problem.  But I was wondering if Guido or someone else added a
>>> builtin function or method that does this automatically for the
>>> programmer.  Or is there an easier way?  Okay.... thanks.  ( In case you're
>>> wondering why I called the function "flatten" it's because I know from
>>> experience that Wolfram Mathematica and Ocaml have these "flatten"
>>> functions.  I think Ruby has something similar, but I haven't played with
>>> Ruby in a while so I'm not really sure. )  The try: except block is
>>> important because you can't subscript non-list data structures in Python.
>>> The IndexError is what you get when you try to index an empty list.  So I
>>> ****think**** my try: except block covers most commonly encountered
>>> exceptions when working with lists embedded within other lists.
>>>
>>> Best,
>>>
>>> Douglas.
>>>
>>> def flatten(lst):
>>> if lst == [ ]:
>>> return lst
>>> else:
>>> try:
>>> return [lst[0][0]] + flatten(lst[0][1:] + lst[1:])
>>> except TypeError:
>>> return [lst[0]] + flatten(lst[1:])
>>> except IndexError:
>>> return flatten(lst[1:])
>>>
>>> def flattenAgain(lst):
>>> newList = lst[:]
>>> while newList != flatten(newList):
>>> newList = flatten(newList)
>>> return newList
>>>
>>>
>>> _______________________________________________
>>> Chicago mailing list
>>> Chicago at python.org<mailto:Chicago at python.org>
>>> https://mail.python.org/mailman/listinfo/chicago
>>>
>>>
>>> _______________________________________________
>>> Chicago mailing list
>>> Chicago at python.org<mailto:Chicago at python.org>
>>> https://mail.python.org/mailman/listinfo/chicago
>>>
>>>
>>>
>>> _______________________________________________
>>> Chicago mailing list
>>> Chicago at python.org<mailto:Chicago at python.org>
>>> https://mail.python.org/mailman/listinfo/chicago
>>>
>>>
>>>
>>> _______________________________________________
>>> Chicago mailing list
>>> Chicago at python.org<mailto:Chicago at python.org>
>>> https://mail.python.org/mailman/listinfo/chicago
>>>
>>>
>>>
>>> _______________________________________________
>>> Chicago mailing list
>>> Chicago at python.org<mailto:Chicago at python.org>
>>> https://mail.python.org/mailman/listinfo/chicago
>>>
>>>
>>> _______________________________________________
>>> Chicago mailing list
>>> Chicago at python.org<mailto:Chicago at python.org>
>>> https://mail.python.org/mailman/listinfo/chicago
>>>
>>>
>>> _______________________________________________
>>> Chicago mailing list
>>> Chicago at python.org<mailto:Chicago at python.org>
>>> https://mail.python.org/mailman/listinfo/chicago
>>>
>>>
>>> _______________________________________________
>>> Chicago mailing list
>>> Chicago at python.org<mailto:Chicago at python.org>
>>> https://mail.python.org/mailman/listinfo/chicago
>>>
>>> _______________________________________________
>>> Chicago mailing list
>>> Chicago at python.org<mailto:Chicago at python.org>
>>> https://mail.python.org/mailman/listinfo/chicago
>>>
>>>
>>>
>>> _______________________________________________
>>> Chicago mailing list
>>> Chicago at python.org<mailto:Chicago at python.org>
>>> https://mail.python.org/mailman/listinfo/chicago
>>>
>>>
>>> _______________________________________________
>>> Chicago mailing list
>>> Chicago at python.org<mailto:Chicago at python.org>
>>> https://mail.python.org/mailman/listinfo/chicago
>>>
>>> _______________________________________________
>>> Chicago mailing list
>>> Chicago at python.org
>>> https://mail.python.org/mailman/listinfo/chicago
>>>
>>
>>
>> _______________________________________________
>> Chicago mailing list
>> Chicago at python.org
>> https://mail.python.org/mailman/listinfo/chicago
>>
>>
>
> _______________________________________________
> Chicago mailing list
> Chicago at python.org
> https://mail.python.org/mailman/listinfo/chicago
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/chicago/attachments/20160218/ac251230/attachment-0001.html>
```