Hlelp clean up clumpsy code

Nick Coghlan ncoghlan at iinet.net.au
Tue Jan 4 05:17:53 EST 2005


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