Python Function Challenge #2

A new year and a new challenge, but this one may force you to think outside the box a bit. Today's challenge is: flattening functions.

Let's say you have a list that is made up of items, some of which are lists. Each of those lists may be made up of items or more lists and so on...

For this challenge, your job is to take a list or tuple as an input and convert it to a flat list or tuple (meaning that all the non-data structure values are present, but all the data structures are removed).

In designing your functions, some of you may want to focus solely on speed, others on creativity, and some of you may want to find a balance of the two... all of these approaches are great. Let's see how many different approaches the Python board can come up with!

OPTIONAL:
If you're feeling particularly hardcore, let's assume that the initial value is a list or tuple, but it can also contain a dictionary. For dictionaries, order the values based on the keys (0-9, A-Z, a-z case sensitive). They keys should not exist in our final result, only their associated flattened values.

This post has been edited by atraub: 06 January 2011 - 08:01 AM
Reason for edit:: removed tuple input

Replies To: Python Function Challenge #2

Re: Python Function Challenge #2

Harhar, atraub finally found a problem for which recursion feels natural.

I will oblige, here is my version. Don't beat me if it is ugly or buggy ... its late at night here:

Spoiler

import collections
def isflat(x):
return not isinstance(x, collections.Container)
def flatten(x):
agregator = []
if isflat(x):
agregator += [x]
else:
if hasattr(x, "keys"):
#quacks like a dict/mapping, so lets treat it as such
keys = x.keys()
keys.sort()
for key in keys:
agregator += flatten(x[key])
elif hasattr(x, "__iter__"):
#quacks like an iterable but is not a mapping
#as we already plucked that duck
for el in x:
agregator += flatten(el)
else:
msg = "Encountered Container that is not dict-like or iterable"
raise TypeError(msg)
#maybe we should treat such an object unchanged
#insted of raising an exception?
return agregator

Re: Python Function Challenge #2

Posted 05 January 2011 - 10:55 PM

I am still kind of a noob in python so my code might be the quickest or best way to do something, but it works. There is probably a way better way to check if the object is a list, but I couldn't get any other way to work. Anyways here is my crack at it, I went for minimalistic.

Re: Python Function Challenge #2

Posted 06 January 2011 - 07:58 AM

Uh oh! It seems no one has managed to write a program that actually fulfills the requirement of being able to work with tuples! Of course, tuples ARE immutable, so flattening a tuple may prove impossible, but surely it's possible to flatten a list with a tuple in it.

Re: Python Function Challenge #2

Posted 06 January 2011 - 08:30 AM

Doh! I overlooked Nallo's! +1 style points to Nallo! Because of that little recursion poke he gave me, I got distracted and completely overlooked his code. Dang Nallo, that's a lot better than anything I came up with!

This post has been edited by atraub: 06 January 2011 - 08:32 AM
Reason for edit:: EXPANSION

Re: Python Function Challenge #2

Posted 07 January 2011 - 12:21 AM

I was trying to do method injection in Python because I'm used to open classes in Ruby but came to the conclusion that it's whacky and convoluted and I don't know enough Python to be patient with it. In other words it reminded me of why i dislike Python in the first place.

But, in Ruby it would be trivial, even ignoring the existing flatten method for collections.