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

Aaron Elmquist elmq0022 at umn.edu
Thu Feb 18 16:13:08 EST 2016


I can't think of a good reason to call "next" explicitly (beside priming a
coroutine, I think.  Not my strong point).  I just included the use of
"next" to drive home the point that this function returns a generator.

As far as recursion, CPython does not implement true "tail calls".  I've
read a quote from the BDFL that he has a preference for stack traces vs
true tail calls.

On Thu, Feb 18, 2016 at 2:01 PM, Lewit, Douglas <d-lewit at neiu.edu> wrote:

> 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,
>>>> I'm just asking about itertools.chain( ).  I am not asking for any other
>>>> 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
>>>> discouraged from asking questions about his "unusual" implementation?
>>>>
>>>>
>>>> https://groups.google.com/forum/#!msg/comp.os.minix/dlNtH7RRrGA/SwRavCzVE7gJ
>>>>
>>>>
>>>> https://groups.google.com/forum/#!topic/comp.os.minix/wlhw16QWltI%5B1-25%5D
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> 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
>>>>
>>>> On Feb 17, 2016, at 10:05 AM, Adam Forsyth <adam at adamforsyth.net
>>>> <mailto:adam at adamforsyth.net>> wrote:
>>>>
>>>> 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.
>>>>
>>>> Adam Forsyth
>>>> Sponsorship Director, ChiPy
>>>>
>>>>
>>>> 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 <
>>>> bradley.marts at gmail.com<mailto:bradley.marts at gmail.com>> wrote:
>>>> 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 your base case.
>>>>
>>>> Brad
>>>>
>>>> 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 <
>>>> bradley.marts at gmail.com<mailto:bradley.marts at gmail.com>> wrote:
>>>> > 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
>>
>>
>
> _______________________________________________
> 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/de4c3553/attachment.html>


More information about the Chicago mailing list