# NEWB: General purpose list iteration?

Discussion in 'Python' started by Donald Newcomb, Aug 12, 2005.

1. ### Donald NewcombGuest

I'm a real Python NEWB and am intrigued by some of Python's features, so I'm
starting to write code to do some things to see how it works. So far I
really like the lists and dictionaries since I learned to love content
addressability in MATLAB. I was wondering it there's a simple routine (I
think I can write a recurisve routine to do this.) to scan all the elements
of a list, descending to lowest level and change something. What I'd like to
do today is to convert everything from string to float. So, if I had a list
of lists that looked like:
[['1.1', '1.2', '1.3'], [['2.1', '2.2'], [['3.1', '3.2'], ['4.1', '4.2']]]]
and I'd like it to be:
[[1.1, 1.2, 1.3], [[2.1, 2.2], [[3.1, 3,2], [4.1, 4.2]]]]
is there just a library routine I can call to do this? Right now, I'm using
'for' loops nested to the maximum depth anticipated.

for i in range(len(list)):
for j in range(len(list)):
for k in range(len(list[j])):
etc
list[j][...] = float(list[j][....])

Which works but is not pretty. I was just looking for a way to say:
listb = float(lista)
However, the way I've started jamming everything into lists and
dictionaries, I'm sure I'll be needing to do other in-place conversions
similar to this in the future.

--
Donald Newcomb
DRNewcomb (at) attglobal (dot) net

Donald Newcomb, Aug 12, 2005

2. ### Devan LGuest

def descend(iterable):
if hasattr(iterable, '__iter__'):
for element in iterable:
descend(element)
else:
do_something(iterable)

This will just do_something(object) to anything that is not an
iterable. Only use it if all of your nested structures are of the same
depth.

If you used it on the following list of lists

[[something],[[something_else],[other_thing]]]

it would modify something, something_else, and other_thing.

Devan L, Aug 12, 2005

3. ### Peter OttenGuest

Donald Newcomb wrote:

> I was wondering it there's a simple routine (I
> think I can write a recurisve routine to do this.) to scan all the
> elements of a list, descending to lowest level and change something. What
> I'd like to do today is to convert everything from string to float. So, if
> I had a list of lists that looked like:
> [['1.1', '1.2', '1.3'], [['2.1', '2.2'], [['3.1', '3.2'], ['4.1',
> [['4.2']]]]
> and I'd like it to be:
> [[1.1, 1.2, 1.3], [[2.1, 2.2], [[3.1, 3,2], [4.1, 4.2]]]]
> is there just a library routine I can call to do this? Right now, I'm
> using 'for' loops nested to the maximum depth anticipated.

A non-recursive approach:

def enumerate_ex(items):
stack = [(enumerate(items), items)]
while stack:
en, seq = stack[-1]
for index, item in en:
if isinstance(item, list):
stack.append((enumerate(item), item))
break
yield index, seq[index], seq
else:
stack.pop()

data = [['1.1', '1.2', '1.3'], [['2.1', '2.2'], [['3.1', '3.2'], ['4.1',
'4.2']]]]

for index, value, items in enumerate_ex(data):
items[index] = float(value)

# Now let's test the algorithm and our luck with float comparisons
assert data == [[1.1, 1.2, 1.3], [[2.1, 2.2], [[3.1, 3.2], [4.1, 4.2]]]]

Peter

Peter Otten, Aug 12, 2005
4. ### Donald NewcombGuest

"Devan L" <> wrote in message
news:...
> This will just do_something(object) to anything that is not an
> iterable. Only use it if all of your nested structures are of the same
> depth.

Cool! I'll try it.

--
Donald Newcomb
DRNewcomb (at) attglobal (dot) net

Donald Newcomb, Aug 12, 2005
5. ### Donald NewcombGuest

"Peter Otten" <> wrote in message
news:ddhh60\$d8s\$00\$-online.com...
> A non-recursive approach:
>
> def enumerate_ex(items):
> stack = [(enumerate(items), items)]
> while stack:
> en, seq = stack[-1]
> for index, item in en:
> if isinstance(item, list):
> stack.append((enumerate(item), item))
> break
> yield index, seq[index], seq
> else:
> stack.pop()

It's going to take me a while to figure out exactly what that does but it
sure does what I wanted it to.
Thanks.

--
Donald Newcomb
DRNewcomb (at) attglobal (dot) net

Donald Newcomb, Aug 12, 2005