439,957 Members | 2,017 Online
Need help? Post your question and get tips & solutions from a community of 439,957 IT Pros & Developers. It's quick & easy.

# len(var) is [CONSTANT] equal to len(var) == [CONSTANT]?

 P: n/a Hi, (len(['']) is 1) == (len(['']) == 1) =True Is this the case for all numbers? I've tried running the following: for i in range(10000): for j in range(10000): if i != j: assert id(i) != id(j), 'i=%d, j=%d, id=%d' % (i, j, id (i)) which executes fine. Hence, 0-9999 is okey... But this is a relatively small range, and sooner or later you probably get two numbers with the same id... Thoughts anyone? Regards Tor Erik PS: For those of you who don't know: keyword is compares object identities Nov 23 '06 #1
14 Replies

 P: n/a Tor Erik Soenvisen wrote: (len(['']) is 1) == (len(['']) == 1) =True Is this the case for all numbers? I'm not sure what you're asking here, but if you digest the following facts, maybe you can answer it yourself: 1) all objects that exist at the same time have distinct identifies, and 2) a Python implementation may or may not hand reuse existing immutable objects that have the same value when asked to create a new object, 3) identities are recycled when objects are deleted, and 4) [] and {} always create a new object every time they're evaluated. Nov 23 '06 #2

 P: n/a Tor Erik Soenvisen wrote: (len(['']) is 1) == (len(['']) == 1) =True Is this the case for all numbers? I've tried running the following: for i in range(10000): ************for*j*in*range(10000): ****************if i != j: ************************assert id(i) != id(j), 'i=%d, j=%d, id=%d' % (i, (i)) Shouldn't the test in the loop be if i == j: assert i is j Of course it would fail... Peter Nov 23 '06 #3

 P: n/a distinct identifies don't trust your spellchucker. Nov 23 '06 #4

 P: n/a "Tor Erik Soenvisen"

 P: n/a On Thu, 23 Nov 2006 10:48:32 +0000, Tor Erik Soenvisen wrote: Hi, (len(['']) is 1) == (len(['']) == 1) =True You shouldn't rely on this behaviour: >>x = 100000len('a' * x) == x True >>len('a' * x) is x False (Your results may vary -- this depends on the implementation.) Is this the case for all numbers? I've tried running the following: for i in range(10000): for j in range(10000): if i != j: assert id(i) != id(j), 'i=%d, j=%d, id=%d' % (i, j, id (i)) which executes fine. Hence, 0-9999 is okey... This doesn't necessarily hold for all integers -- again, it depends on the implementation, the precise version of Python, and other factors. Don't rely on "is" giving the same results as "==". >>(1+2+3+4+5)**7 == 15**7 True >>(1+2+3+4+5)**7 is 15**7 False But this is a relatively small range, and sooner or later you probably get two numbers with the same id... Thoughts anyone? No, you will never get two objects existing at the same time with the same id. You will get two objects that exist at different times with the same id, since ids may be reused when the object is deleted. PS: For those of you who don't know: keyword is compares object identities Exactly. There is no guarantee that any specific integer object "1" must be the same object as another integer object "1". It may be, but it isn't guaranteed. I think the only object that is guaranteed to hold for is None. None is a singleton, so there is only ever one instance. Hence, you should test for None with "obj is None" rather than ==, because some custom classes may do silly things with __eq__: class Blank(object): """Compares equal to anything false, including None.""" def __eq__(self, other): return not other -- Steven. Nov 23 '06 #6

 P: n/a Steven D'Aprano Hi, (len(['']) is 1) == (len(['']) == 1) =True You shouldn't rely on this behaviour: >>>x = 100000len('a' * x) == x True >>>len('a' * x) is x False (Your results may vary -- this depends on the implementation.) >Is this the case for all numbers? I've tried running the following:for i in range(10000): for j in range(10000): if i != j: assert id(i) != id(j), 'i=%d, j=%d, id=%d' % (i, j, id(i))which executes fine. Hence, 0-9999 is okey... This doesn't necessarily hold for all integers -- again, it depends on the implementation, the precise version of Python, and other factors. Don't rely on "is" giving the same results as "==". >>>(1+2+3+4+5)**7 == 15**7 True >>>(1+2+3+4+5)**7 is 15**7 False >But this is a relativelysmall range, and sooner or later you probably get two numbers withthe same id... Thoughts anyone? No, you will never get two objects existing at the same time with the same id. You will get two objects that exist at different times with the same id, since ids may be reused when the object is deleted. >PS: For those of you who don't know: keyword is compares objectidentities Exactly. There is no guarantee that any specific integer object "1" must be the same object as another integer object "1". It may be, but it isn't guaranteed. I think the only object that is guaranteed to hold for is None. None is a singleton, so there is only ever one instance. Hence, you should test for None with "obj is None" rather than ==, because some custom classes may do silly things with __eq__: class Blank(object): """Compares equal to anything false, including None.""" def __eq__(self, other): return not other I've seen code like this: if type([]) is list: print 'Is list' which seem to work. And also I've seen "var is None", as you mention. Nov 23 '06 #7

 P: n/a Steven D'Aprano wrote: No, you will never get two objects existing at the same time with the same id. You will get two objects that exist at different times with the same id, since ids may be reused when the object is deleted. I think it is worth pointing out that this is an area where people get confused quite often; it is very easily to get misleading results when you call the id() function. e.g. >>class C: def f(self): pass def g(self): pass >>c = C()id(c.f)==id(c.g) True >>c.f is c.g False The ids are the same here only because the objects do not exist at the same time. In the first comparison c.f is an expression which creates a temporary object that is destroyed before the expression involving c.g is evaluated, so it is possible for the different objects to have the same id. In the second comparison the objects exist at the same time so they are forced to have different ids. Nov 23 '06 #8

 P: n/a Tor Erik Soenvisen

 P: n/a Tor Erik Soenvisen wrote: I've seen code like this: if type([]) is list: print 'Is list' which seem to work. And also I've seen "var is None", as you mention. None is guaranteed to be a singleton: http://effbot.org/pyref/type-none.htm Why "is" works for type objects should be pretty obvious, of course. Nov 23 '06 #10

 P: n/a Tor Erik Soenvisen wrote: (len(['']) is 1) == (len(['']) == 1) =True >>len(['']) 1 >>len(['']) is 1 True >>len(['']) == 1 True >>True == True True >>(len(['']) is 1) == (len(['']) == 1) True What did you expect? Stefan Nov 23 '06 #11

 P: n/a Fredrik Lundh wrote: 4) [] and {} always create a new object every time they're evaluated. Not quite. The empty tuple is cached: >>a = ()b = ()a is b True Cheers, Brian Nov 23 '06 #12

 P: n/a Brian Quinlan wrote: >4) [] and {} always create a new object every time they're evaluated. Not quite. The empty tuple is cached: >>a = () >>b = () >>a is b True () isn't [] or {}, though. time to switch to a bigger font? ;-) Nov 23 '06 #13

 P: n/a Fredrik Lundh wrote: Brian Quinlan wrote: >>4) [] and {} always create a new object every time they're evaluated. Not quite. The empty tuple is cached: > >>a = ()b = ()a is b True () isn't [] or {}, though. time to switch to a bigger font? ;-) Yeah, sorry I'm an idiot. I can't believe that I've been able to program successfully for so long when I can't recognize the different between a dictionary and a tuple :-) Cheers, Brian Nov 23 '06 #14

 P: n/a Tor Erik Soenvisen (len(['']) is 1) == (len(['']) == 1) =TrueIs this the case for all numbers? I've tried running the following:for i in range(10000): for j in range(10000): if i != j: assert id(i) != id(j), 'i=%d, j=%d, id=%d' % (i, j, id(i))which executes fine. Hence, 0-9999 is okey... But this is a relativelysmall range, and sooner or later you probably get two numbers with the sameid... Thoughts anyone? It has been my experience that virtually every use of the "is" operator (except "is None") is wrong. Now, I fully understand that there are perfectly valid uses for "is", and the standard library contains a few, but for the non-guru casual Python programmer, I think it is safe to say "never use 'is'". -- Tim Roberts, ti**@probo.com Providenza & Boekelheide, Inc. Nov 23 '06 #15

### This discussion thread is closed

Replies have been disabled for this discussion.