disgrating a list
Tim Chase
python.list at tim.thechases.com
Fri Sep 1 14:14:31 EDT 2006
jwaixs wrote:
> Hello,
>
> How can I disgrate (probably not a good word for it) a list? For
> example:
>
> a = [1,2]
> b = 3
> c = [a] + [b] # which makes [[1,2],3]
>
> Then how can I change c ([[1,2],3]) into [1,2,3]? I have a simple
> function for this:
> ========================
> def flatten(l):
> r = []
> s = [l]
> while len(s) > 0:
> i = s.pop()
> if i.__class__ == list:
> for c in i:
> s.append(c)
> else:
> r.append(i)
> return r
> ========================
> But this function isn't really doing it in the "python-way". Doesn't
> have python an obscure function or buildin to do this?
I'm not sure what makes it against "the python-way"...I would
likely just use a "for" loop structure rather than a while loop.
I would also skip copying the parameter and popping its
elements off. Lastly, I would use a slightly broader test than
asking if the item is a list (to handle sub-classes, sets,
dictionaries, etc):
>>> def flatten(x):
... q = []
... for v in x:
... if hasattr(v, '__iter__'):
... q.extend(flatten(v))
... else:
... q.append(v)
... return q
...
>>> flatten([1,2,3])
[1, 2, 3]
>>> flatten([1,2,3, [5,6]])
[1, 2, 3, 5, 6]
>>> flatten([1,2,3, [5,6, [7,8]]])
[1, 2, 3, 5, 6, 7, 8]
>>> flatten([1,2,3, [5, {1:3,5:1},6, set([7,8])]])
[1, 2, 3, 5, 1, 5, 6, 8, 7]
I'm not sure if '__iter__' is the right thing to be looking for,
but it seems to work at least for lists, sets, dictionarys (via
their keys), etc. I would use it because at least then you know
you can iterate over it
I don't know of any builtin that will go to arbitrary depths, and
haven't figured out a clean way to do this with any sort of
list-comprehension, reduce/map call, or anything of the like.
The ability to flatten requires recursing down nested data
structures...recursion is something that list comprehensions,
map()/reduce() commands, etc. aren't so good as (at least as far
as I've learned).
-tkc
More information about the Python-list
mailing list