2

I have a weird problem with python passing a list as parameter to a function. Here is the code:

def foobar(depth, top, bottom, n=len(listTop)):
    print dir(top)
    print top.append("hi")
    if depth > 0:
        exit()
    foobar(depth+1, top.append(listTop[i]), bottom.append(listBottom[i]))

top = bottom = []
foobar(0, top, bottom)

It says "AttributeError: 'NoneType' object has no attribute 'append'", because top is None in foobar although dir(top) prints a full attribute and method list of a type list. So whats wrong? I just wanted to pass two lists as parameters to this recursive function.

Cravid
  • 653
  • 2
  • 7
  • 22
  • 1
    In your example, `top` and `bottom` refer to the same list, and this will lead to (maybe) unexpected results in your code. (`t = b = [];t.append(1);print b`) – jorgeca Nov 25 '12 at 21:18
  • This wasn't the reason of the described problem, but it solved another one i didn't noticed yet. So thanks either way. – Cravid Nov 26 '12 at 09:14
  • Glad it helped. And that's why I didn't post it as an answer ;) – jorgeca Nov 26 '12 at 14:39

2 Answers2

12

You pass in the result of top.append() to your function. top.append() returns None:

>>> [].append(0) is None
True

You need to call .append() separately, then pass in just top:

top.append(listTop[i])
bottom.append(listBottom[i])
foobar(depth+1, top, bottom)

Note that the n=len(listTop) argument in the function is both redundant and only ever executed once, namely when you create the function. It won't be evaluated each time you call the function. You can omit it safely from the version you posted here in any case.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Yeah, i thought it would return the list... so thanks, that solved it. That n is only set on creation is deliberate. – Cravid Nov 26 '12 at 09:15
2

top.append(listTop[i]) works in place and returns None

applicative_functor
  • 4,926
  • 2
  • 23
  • 34