By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,907 Members | 1,932 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,907 IT Pros & Developers. It's quick & easy.

Why would I get a TypeEror?

P: n/a
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?

Thanks,
Jul 18 '05 #1
Share this Question
Share on Google+
14 Replies


P: n/a
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?


What did you expect the "length" of the integer 3 to be?

-Peter
Jul 18 '05 #2

P: n/a

On 12.01.2005, at 18:35, 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?


because len() works only for sequence and mapping objects:
help(len)

Help on built-in function len in module __builtin__:

len(...)
len(object) -> integer

Return the number of items of a sequence or mapping.

- harold -

--
Ceci n'est pas une signature.
--

Jul 18 '05 #3

P: n/a

On 12.01.2005, at 18:35, 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?


the problem is, that (1,len(a)) is evaluated, neither what type a
actually has
(python has no builtin lazy evaluation like ML). You have to do it this
way
instead:

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

- harold -

--
The opposite of a correct statement is a false statement.
But the opposite of a profound truth may be another profound truth.
-- Niels Bohr

Jul 18 '05 #4

P: n/a
Sorry if my question was a little "lazy" and yes, I was asking about the
"lazy evaluation". :=)

I am surprised about this (and this can be dangerous, I guess).

If this is true, I would run into trouble real quick if I do a:

(1/x,1.0e99)[x==0]

and that's not good.

Something to keep in mind. :-(
"harold fellermann" <ha***************@upf.edu> wrote in message
news:ma**************************************@pyth on.org...

On 12.01.2005, at 18:35, 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?


the problem is, that (1,len(a)) is evaluated, neither what type a
actually has
(python has no builtin lazy evaluation like ML). You have to do it this
way
instead:

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

- harold -

--
The opposite of a correct statement is a false statement.
But the opposite of a profound truth may be another profound truth.
-- Niels Bohr

Jul 18 '05 #5

P: n/a
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?

Thanks,

because the interpreter evaluates the tuple (1, len(a)) before applying
the indexing to it.

You are trying to be far too clever. The standard way to write this
would be:

a = 3
.....
b = 1
if isinstance(a,(list,tuple,dict)):
b = len(a)

Is code length *really* so important? Think carefully ...

regards
Steve
--
Steve Holden http://www.holdenweb.com/
Python Web Programming http://pydish.holdenweb.com/
Holden Web LLC +1 703 861 4237 +1 800 494 3119
Jul 18 '05 #6

P: n/a

"Peter Hansen" <pe***@engcorp.com> wrote in message
news:XO********************@powergate.ca...
What did you expect the "length" of the integer 3 to be?


Perhaps 2 (bits in a minimal binary representation).

I once, for maybe a minute, considered proposing this as an overloaded
meaning of len, but realized that that would more often mask errors than
save time.

If case bits(i) is what the OP wants:

def bits(i):
i = abs(i)
b = 0
while i:
i >>= 1
b += 1
return b

Terry J. Reedy

Jul 18 '05 #7

P: n/a
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
Jul 18 '05 #8

P: n/a
It's me wrote:
Sorry if my question was a little "lazy" and yes, I was asking about the
"lazy evaluation". :=)

I am surprised about this (and this can be dangerous, I guess).

If this is true, I would run into trouble real quick if I do a:

(1/x,1.0e99)[x==0]

and that's not good.

Something to keep in mind. :-(


Lazy evaluation: use the (x==0 and 1e99 or 1/x) form!

Reinhold
Jul 18 '05 #9

P: n/a
Say again???

"Reinhold Birkenfeld" <re************************@wolke7.net> wrote in
message news:34*************@individual.net...
It's me wrote:
Sorry if my question was a little "lazy" and yes, I was asking about the
"lazy evaluation". :=)

I am surprised about this (and this can be dangerous, I guess).

If this is true, I would run into trouble real quick if I do a:

(1/x,1.0e99)[x==0]

and that's not good.

Something to keep in mind. :-(


Lazy evaluation: use the (x==0 and 1e99 or 1/x) form!

Reinhold

Jul 18 '05 #10

P: n/a
It's me wrote:
Say again???

"Reinhold Birkenfeld" <re************************@wolke7.net> wrote in
message news:34*************@individual.net...
It's me wrote:
> Sorry if my question was a little "lazy" and yes, I was asking about the
> "lazy evaluation". :=)
>
> I am surprised about this (and this can be dangerous, I guess).
>
> If this is true, I would run into trouble real quick if I do a:
>
> (1/x,1.0e99)[x==0]
>
> and that's not good.
>
> Something to keep in mind. :-(


Lazy evaluation: use the (x==0 and 1e99 or 1/x) form!

Reinhold


Say what again?

Reinhold

PS: Please do not produce top-posting!
Jul 18 '05 #11

P: n/a
It's me wrote:
Say again???
Please stop top-posting -- it makes it hard to reply in context.
"Reinhold Birkenfeld" wrote...
It's me wrote:
If this is true, I would run into trouble real quick if I do a:

(1/x,1.0e99)[x==0]


Lazy evaluation: use the (x==0 and 1e99 or 1/x) form!


If you want short-circuting behavior, where only one of the two branches
gets executed, you should use Python's short-circuiting boolean
operators. For example,

(x == 0 and 1.0e99 or 1/x)

says something like:

Check if x == 0.
If so, check if 1.0e99 is non-zero. It is, so return it.
If x != 0, see if 1/x is non-zero. It is, so return it.

Note that if you're not comfortable with short-circuiting behavior, you
can also code this using lazy evaluation:

(lambda: 1/x, lambda: 1.0e99)[x==0]()

This says something like:

Create two functions, one to produce 1/x and one to produce 1.0e99.
Select one of these functions depending on whether or not x==0
Invoke the chosen function.

HTH,

Steve
Jul 18 '05 #12

P: n/a
Steven Bethard wrote:
It's me wrote:
Say again???


Please stop top-posting -- it makes it hard to reply in context.
"Reinhold Birkenfeld" wrote...
It's me wrote:
If this is true, I would run into trouble real quick if I do a:

(1/x,1.0e99)[x==0]

Lazy evaluation: use the (x==0 and 1e99 or 1/x) form!


If you want short-circuting behavior, where only one of the two branches
gets executed, you should use Python's short-circuiting boolean
operators. For example,

(x == 0 and 1.0e99 or 1/x)

says something like:

Check if x == 0.
If so, check if 1.0e99 is non-zero. It is, so return it.
If x != 0, see if 1/x is non-zero. It is, so return it.

Note that if you're not comfortable with short-circuiting behavior, you
can also code this using lazy evaluation:

(lambda: 1/x, lambda: 1.0e99)[x==0]()


Or even

(x==0 and lambda: 1e99 or lambda: 1/x)()

Or ...
Reinhold
Jul 18 '05 #13

P: n/a
På 14. jan 2005 kl. 22:58 skrev Steven Bethard:

(Any mac users? How do I fix this to appear in Norwegian? =)
Note that if you're not comfortable with short-circuiting behavior,
you can also code this using lazy evaluation:

(lambda: 1/x, lambda: 1.0e99)[x==0]()


... and people wonder why so many Python people want to get rid of
Lambda =)

--
Stian Søiland You can't say civilization don't
Trondheim, Norway advance, however, for in every war
http://www.soiland.no/ they kill you in a new way. [Rogers]
=/\=

Jul 18 '05 #14

P: n/a
Stian Soiland wrote:
På 14. jan 2005 kl. 22:58 skrev Steven Bethard:

(Any mac users? How do I fix this to appear in Norwegian? =)
Note that if you're not comfortable with short-circuiting behavior,
you can also code this using lazy evaluation:

(lambda: 1/x, lambda: 1.0e99)[x==0]()

.. and people wonder why so many Python people want to get rid of Lambda =)


Heh heh. No I don't. ;)

In fact, I don't ever use lambdas in any of my own "real" code. But I
don't mind being a little dirty when I post to c.l.py. ;) I guess I
could have written this as:

def inverse():
return 1/x
def largenum():
return 1.0e99
b = (inverse, largenum)[x==0]()

but I'm usually too lazy, and it's an ugly solution anyway, compared to
the simple one which the OP was apparently trying to avoid:

if x != 0:
b = 1/x
else:
b = 1.0e99

=)

Steve
Jul 18 '05 #15

This discussion thread is closed

Replies have been disabled for this discussion.