473,326 Members | 2,113 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,326 software developers and data experts.

Hlelp clean up clumpsy code

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?

Thanks,

Jul 18 '05 #1
6 1132
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?


Don't know what version of Python you're using, but if you're using 2.4
(or with a few slight modifications, with 2.3), you can write:

py> dict((item, i+1)
.... for i, item in enumerate(
.... a_sub_item
.... for a_item in a
.... for a_sub_item
.... in isinstance(a_item, (int, long)) and [a_item] or a_item))
{8: 4, 1: 1, 2: 3, 4: 5, 5: 2}

Basically, I use a generator expression to flatten your list, and then
use enumerate to count the indices instead of keeping the i variable.

Steve
Jul 18 '05 #2
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 | nc******@email.com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net
Jul 18 '05 #3
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" <nc******@iinet.net.au> wrote in message
news:ma**************************************@pyth on.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 | nc******@email.com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net

Jul 18 '05 #4
Nick Coghlan wrote:
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


Avoiding LBYL gives you:
def flatten(seq):
for x in seq:
try:
for y in flatten(x):
yield y
except TypeError:
yield x

--Scott David Daniels
Sc***********@Acm.Org
Jul 18 '05 #5
Scott David Daniels wrote:
Nick Coghlan wrote:
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

Avoiding LBYL gives you:
def flatten(seq):
for x in seq:
try:
for y in flatten(x):
yield y
except TypeError:
yield x


If I'm not mistaken, this will result in infinite recursion on
strings. 'for x in aString' will iterate over the characters in the
string, even if the string is only a single character, so "for y in
flatten('a'):" will not give a type error. You'd need to add
special-case tests to watch for this condition (and try not to be too
special-case and allow unicode objects to pass).

Nick's version works on strings (and unicode objects) because they
lack an __iter__() method, even though they follow the (older)
sequence protocol.

Jeff Shannon
Technician/Programmer
Credit International

Jul 18 '05 #6
You can also do it in a more pythonic way but without generators :

# a = [[1,5,2], 8, 4]
# l = []
# for item in a:
# if isinstance(item, (int, long)):
# l.append(item)
# else:
# l+=item
# print dict([(item,i+1) for (i,item) in enumerate(l)])

It works in the same conditions as your original code (no nested lists)

A few other things :
- you don't have to type a comma for one-item lists : x = [x] works -
you probably confused with tuples where you must do x=(x,)
- instead of
# for w in [y for y in x]:
just do
# for w in x:
- for "i = i+1" there is a shortcut : i+=1 (see "l+=item" above)

Regards,
Pierre
Jul 18 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Craig Thomson | last post by:
I was wondering what people do with text provided by the user in a form. Some cleaning needs to be done at some stage if you are going to be putting it in a database or displaying it etc. But when...
15
by: lallous | last post by:
Hello, I have a function like: void fnc() { char *mem1, *mem2, *mem3, *mem4; // lots of code... // mem1, 2, 3, 4 got allocated // lots of code and condition checks if (condition_failed)
17
by: Christopher Benson-Manica | last post by:
Yesterday I changed some code to use std::vectors and std::strings instead of character arrays. My boss asked me today why I did it, and I said that the code looks cleaner this way. He countered...
10
by: lallous | last post by:
Hello, This question was asked in comp.lang.c++ and the answers involved the use of objects whose destructors are automatically called when getting out of scope, however I was expecting...
7
by: Felix Kater | last post by:
Hi, when I need to execute a general clean-up procedure (inside of a function) just before the function returns -- how do I do that when there are several returns spread over the whole function?...
5
by: Rob | last post by:
I have a simple application consisting of about 4 forms and a few db connections... I would like to make sure that I have done proper clean up when the user exits the application. For all...
1
by: KevinGPO | last post by:
I got ASP code (VBScript mixed with HTML & Javascript) and am looking for a clean/tidy program to clean up my code. Should I use Dreamweaver cleanup, tool?
25
by: Koliber (js) | last post by:
sorry for my not perfect english i am really f&*ckin angry in this common pattern about dispose: ////////////////////////////////////////////////////////// Public class...
11
by: Phillip B Oldham | last post by:
I'm wondering whether anyone can offer suggestions on FOSS projects/ apps which exhibit solid OO principles, clean code, good inline documentation, and sound design principles? I'm devoting some...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.