2

Possible Duplicate:
Flatten (an irregular) list of lists in Python

While trying to flatten lists I run into infinite recursion if I pass strings. To my understanding this occurs as the first element of a string is again a string, which in turn can be iterated over. I solved this by seeing if my element quacks like a string, hence the second exception. This seems rather messy. Also, the real problem comes from the fact that strings have no 'base case' to their recursion. Are there other objects which have this property?

Does anyone have a cleaner solution?

def nestedsum(lst, init_sum):
    for itm in lst:
        try:
            init_sum +=itm
        except TypeError as e:
            #check if we have some string iterator
            # as this can cause infinite recurrsion
            try:
                itm + ''            
            except TypeError as e2:
                init_sum +=nestedsum(itm)             
            else:
                raise TypeError("Strings cannot be summed over")
    return init_sum

Thanks in advance. Sorry if there is a similar post somewhere but I had no luck finding it.

Community
  • 1
  • 1
Nick
  • 873
  • 1
  • 6
  • 7
  • Why not check to see if it is a list or tuple? – Snakes and Coffee Aug 24 '12 at 07:31
  • Can you test whether an object is any type of number? I think that will help not raise and afterwards catch any exceptions. – Lyubomir Vasilev Aug 24 '12 at 07:32
  • 1
    @jamylak Thanks that does indeed answer my question. Thanks! – Nick Aug 24 '12 at 07:35
  • Can you show a sample of input and expected (or desired) output? – sberry Aug 24 '12 at 07:36
  • I suppose my question should have been phrased with more emphasis on the part about whether there are other iterable objects that have this infinite behavior other than strings. If so, then I should just restrict function to the specific iterables I want. If not, then I just check that I don't have strings. – Nick Aug 24 '12 at 07:48

2 Answers2

1

I believe this will do what you want, and works with strings as well.

def nestedsum(lst, init_sum):
    for itm in lst:
        if isinstance(itm, (float, int)):
            init_sum += itm
        elif isinstance(itm, (tuple, list)):
            init_sum += nestedsum(itm, init_sum)
        else:
            continue
    return init_sum
sberry
  • 128,281
  • 18
  • 138
  • 165
0

Probably a better way, but you can check if the item is a list using isinstance().

def sum_messy_nest(l, current=0):
    for item in l:
        if isinstance(item, int) or isinstance(item, float):
            current += item
        elif isinstance(item, list):
            current += n(item, current)
        else:
            raise TypeError("I don't know this: {}".format(repr(item)))
    return current
monkut
  • 42,176
  • 24
  • 124
  • 155