0

For some reason I can't get isinstance() to work on Python 2.7.2

def print_lol(the_list, indent=False, level=0):
    for item in the_list:
        if isinstance(item, list):
            print_lol(item, indent, level+1)
        else:
            print(item)

And when I compile and run it:

>>> list = ["q", "w", ["D", ["E", "I"]]]
>>> print_lol(list)

I get the error message:

if isinstance(item, list):
TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types

What am I mising?

2
  • 2
    Everybody makes a list called list in almost every python problem on SO... Commented Apr 14, 2012 at 6:10
  • 1
    @jamylak It's a mistake almost everyone has to make once :) Commented Apr 14, 2012 at 6:13

4 Answers 4

8

You've named your variable list:

>>> list = ["q", "w", ["D", ["E", "I"]]]

Which is hiding the built-in list.

Once you've renamed your variable, restart Python (or your IDE). Since your list is a global variable, it will stick around otherwise.

Sign up to request clarification or add additional context in comments.

3 Comments

You can also re-bind list manually: import __builtin__; list = __builtin__.list will do the trick in this case.
@torek: that's not the ideal way; the best way is del list. Then list will go back to being the built-in type.
@ChrisMorgan: interesting, never knew that before. Doesn't work with other (non-builtins) overwrites that you want to recover from in the interpreter, of course. :-)
2

This is where you have issue

>>> list = ["q", "w", ["D", ["E", "I"]]]

overwriting python named types like list binds the variable name with a new object instance. So later when you tried isinstance with list it failed.

When ever you create new variable, please refrain from naming it differently from built-in and not to conflict with the namespace.

In this example using the following would work like a breeze

>>> mylist = [w for w in mylist if len(w) >= 3 and diff(w)]
>>> isinstance(mylist,list)
True

Please note, if you have polluted the namespace and you are running in IDLE, restarting IDLE is a good alternative.

3 Comments

It doesn't "bind a new behavior to an existing type". The type still functions exactly the same, the name just doesn't point to the type any more.
@agf: Ahh typo I mean bind to a variable
It doesn't bind anything to something existing. It creates a name, list, in the global namespace, which hides the list name in the builtin namespace.
1

The problem is you have shadowed the built-in list by assigning to a variable called list:

list = ["q", "w", ["D", ["E", "I"]]]

You should try to avoid using any of the built-in names for variables, because this will often result in confusing errors. The solution is to use a different name for your variable.

Comments

1

You are overwriting list, try print list before isinstance to diagnose this sort of problem.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.