Why would I get a TypeEror?

Steven Bethard steven.bethard at gmail.com
Wed Jan 12 20:17:17 EST 2005


It's me wrote:
> For this code snip:
> 
> a=3
> ....
> b=(1,len(a))[isinstance(a,(list,tuple,dict))]
> 
> Why would I get a TypeError from the len function?

You're looking for lazy evaluation or short-circuiting behavior.  Python 
provides one form of short circuiting behavior with 'and' and 'or', 
though you need to be careful.  In your particular circumstances, you 
could write this code as:

b = not isinstance(a, (list, tuple, dict)) and 1 or len(a)

Some example code:

py> def b(a):
...     return not isinstance(a, (list, tuple, dict)) and 1 or len(a)
...
py> b(3)
1
py> b([])
0
py> b([3, 4])
2

Note however that, due to how 'and' and 'or' short-circuit, you cannot 
write your code as:

b = isinstance(a, (list, tuple, dict)) and len(a) or 1

because when len(a) is 0, 1 will be returned instead of 0:

py> def b(a):
...     return isinstance(a, (list, tuple, dict)) and len(a) or 1
...
py> b(3)
1
py> b([])
1
py> b([3, 4])
2

If you want lazy evaluation, you can do this with lambdas (though I 
wouldn't advise it):

b = (lambda: 1, lambda: len(a))[isinstance(a,(list,tuple,dict))]()

Note that I select which function using isinstance as you have before, 
and then invoke the selected function with the final ().

Steve



More information about the Python-list mailing list