Hlelp clean up clumpsy code

It's me itsme at yahoo.com
Tue Jan 4 10:12:36 EST 2005


Thanks, Steve and Nick.

Yes, that's what I need to do.   I didn't know it's call "flattening" a list
structure but that's precisely what I needed to do.

Steve,

I am using 2.3 and so I will go with Nick's version.

Thanks to both for helping.


"Nick Coghlan" <ncoghlan at iinet.net.au> wrote in message
news:mailman.121.1104833878.22381.python-list at python.org...
> It's me wrote:
> > Another newbie question.
> >
> > There must be a cleaner way to do this in Python:
> >
> > #### section of C looking Python code ####
> > a = [[1,5,2], 8, 4]
> > a_list = {}
> > i = 0
> > for x in a:
> >     if isinstance(x, (int, long)):
> >         x = [x,]
> >     for w in [y for y in x]:
> >         i = i + 1
> >         a_list[w] = i
> > print a_list
> > #####
> >
> > The code prints what I want but it looks so "C-like".  How can I make it
> > more Python like?
>
> Firstly, calling your dictionary "a_list" is evil. . .
>
> Secondly, explaining what you want the code to do in English is handy when
> asking for help cleaning up code (since we then know which features are
> deliberate, and which are accidental implementation artificacts).
>
> If I'm reading the code correctly, you want to flatten a data structure
which
> may contain either substructures or actual elements.
>
> A custom generator will do nicely:
>
> Py> def flatten(seq):
> ...   for x in seq:
> ...     if hasattr(x, "__iter__"):
> ...       for y in flatten(x):
> ...         yield y
> ...     else:
> ...       yield x
> ...
> Py> data = [[1,5,2],8,4]
> Py> val_to_pos = {}
> Py> for i, x in enumerate(flatten(data)):
> ...   val_to_pos[x] = i + 1
> ...
> Py> print val_to_pos
> {8: 4, 1: 1, 2: 3, 4: 5, 5: 2}
>
> Not any shorter, but this version works correctly for any leaf elements
which
> don't supply __iter__ (e.g. strings), and internal elements which do (e.g.
> tuples) and the depth is limited only by the maximum level of recursion.
Don't
> try to flatten a circular structure, though :)
>
> You may not even need to write the generator, since if you have Tkinter,
that
> already supplies a near-equivalent function:
>
> Py> from Tkinter import _flatten as flatten
> Py> data = [[1,5,2],8,4]
> Py> val_to_pos = {}
> Py> for i, x in enumerate(flatten(data)):
> ...   val_to_pos[x] = i + 1
> ...
> Py> print val_to_pos
> {8: 4, 1: 1, 2: 3, 4: 5, 5: 2}
>
> It even works with strings as leaf elements:
>
> Py> data = [["abc","def",2],8,"xyz"]
> Py> flatten(data)
> ('abc', 'def', 2, 8, 'xyz')
>
> Cheers,
> Nick.
>
> -- 
> Nick Coghlan   |   ncoghlan at email.com   |   Brisbane, Australia
> ---------------------------------------------------------------
>              http://boredomandlaziness.skystorm.net





More information about the Python-list mailing list