Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Puzzled by "is"

0 views
Skip to first unread message

Dick Moores

unread,
Aug 9, 2007, 1:38:46 PM8/9/07
to pytho...@python.org
>>> () is ()
True
>>> (1,) is (1,)
False

Why?

Thanks,

Dick Moores

Jay Loden

unread,
Aug 9, 2007, 1:46:51 PM8/9/07
to Dick Moores, pytho...@python.org

>From the docs for 'is':

Bill Scherer

unread,
Aug 9, 2007, 1:46:53 PM8/9/07
to pytho...@python.org
Dick Moores wrote:
> >>> () is ()
> True
> >>> (1,) is (1,)
> False
>
> Why?
>

>>> a = ()
>>> b = ()
>>> c = (1,)
>>> d = (1,)
>>> a is b
True
>>> c is d
False
>>> id(a)
3086553132
>>> id(b)
3086553132
>>> id(c)
3086411340
>>> id(d)
3086390892


There is only one empty tuple.
Does that clear it up for you?

> Thanks,
>
> Dick Moores
>
>

Neil Cerutti

unread,
Aug 9, 2007, 1:50:47 PM8/9/07
to
On 2007-08-09, Dick Moores <r...@rcblue.com> wrote:
> >>> () is ()
> True
> >>> (1,) is (1,)
> False
>
> Why?

From _Python Reference Manual_: 5.2.4 List displays:

An empty pair of parentheses yields an empty tuple object.
Since tuples are immutable, the rules for literals apply (i.e.,
two occurrences of the empty tuple may or may not yield the
same object).

--
Neil Cerutti

Jay Loden

unread,
Aug 9, 2007, 1:49:30 PM8/9/07
to Dick Moores, pytho...@python.org

Jay Loden wrote:


> Dick Moores wrote:
>> >>> () is ()
>> True
>> >>> (1,) is (1,)
>> False
>>
>> Why?
>>

>> Thanks,
>>
>> Dick Moores
>


>From the docs for 'is':

The operators is and is not test for object identity: x is y is true if
and only if x and y are the same object. x is not y yields the inverse
truth value.

So you're actually testing whether or not the identity of the object is the
same, not whether (1,) == (1,):

>>> (1,) == (1,)
True
>>> id((0,)) == id((0,))
False

-Jay

Dick Moores

unread,
Aug 9, 2007, 3:40:57 PM8/9/07
to pytho...@python.org
At 10:46 AM 8/9/2007, Bill Scherer wrote:
>Dick Moores wrote:
> > >>> () is ()
> > True
> > >>> (1,) is (1,)
> > False
> >
> > Why?
> >
>
> >>> a = ()
> >>> b = ()
> >>> c = (1,)
> >>> d = (1,)
> >>> a is b
>True
> >>> c is d
>False
> >>> id(a)
>3086553132
> >>> id(b)
>3086553132
> >>> id(c)
>3086411340
> >>> id(d)
>3086390892
>
>
>There is only one empty tuple.
>Does that clear it up for you?

But isn't that the same as saying, "That's just the reality of
Python; it is what it is."? I want to know why there is only one
empty tuple, but more than one (1,).

Also,
>>> [] is []
False

Dick

Steve Holden

unread,
Aug 9, 2007, 3:53:28 PM8/9/07
to pytho...@python.org
Dick Moores wrote:
> At 10:46 AM 8/9/2007, Bill Scherer wrote:
>> Dick Moores wrote:
[...]

>> There is only one empty tuple.
>> Does that clear it up for you?
>
> But isn't that the same as saying, "That's just the reality of
> Python; it is what it is."? I want to know why there is only one
> empty tuple, but more than one (1,).
>
Why? Because.

Seriously, it's just an optimization by the implementers. There is no
need for more than one empty tuple, since tuples can never be modified
once created.

But they decided not to create (1, ) in advance. They probably knew that
hardly anybody would want to create that tuple ;-) [Seriously: if you
started trying to predict which tuples would be used you would go
insane, but the empty tuple is the most likely candidate].

> Also,
> >>> [] is []
> False
>
In that case it would definitely NOT make sense to have them the same
list. Python always ensures that the [] constructor creates a new list,
since that list may be bound to one or more variables and mutated. You
wouldn't want

a = []
b = []
a.append("boo!")

to change b so it was no longer an empty list. If you wanted a and b to
reference the same list you would change the second statement to

b = a

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://del.icio.us/steve.holden
--------------- Asciimercial ------------------
Get on the web: Blog, lens and tag the Internet
Many services currently offer free registration
----------- Thank You for Reading -------------

John K Masters

unread,
Aug 9, 2007, 4:21:22 PM8/9/07
to pytho...@python.org

OK fiddling around with this and reading the docs I tried:-
a = 'qqqqqqqqqq' #10 q's
b = 'qqqqqqqqqq' #10 q's
a is b
true
c = 'q' * 10
c
'qqqqqqqqqq' #10 q's
d = 'q' * 10
d
'qqqqqqqqqq' #10 q's
c is d
false

So from what I've read "==" tests for equivalence, "is" tests for identity but
that does not explain the behaviour above.

Regards, John
--
War is God's way of teaching Americans geography
Ambrose Bierce (1842 - 1914)

kyos...@gmail.com

unread,
Aug 9, 2007, 4:24:48 PM8/9/07
to

Steve,

I thought you'd probably weigh in on this esoteric matter. Very
illuminating, as usual.

Mike

Neil Cerutti

unread,
Aug 9, 2007, 4:28:57 PM8/9/07
to

CPython is full of cute little optimizations, and one of them is
that literal strings less than a certain length are 'interned'.
This makes them very fast to compare for equality, and cheaper to
store (maybe?).

> a is b
> true
> c = 'q' * 10
> c
> 'qqqqqqqqqq' #10 q's
> d = 'q' * 10
> d
> 'qqqqqqqqqq' #10 q's
> c is d
> false
>
> So from what I've read "==" tests for equivalence, "is" tests
> for identity but that does not explain the behaviour above.

The 10 q's constructed with string arithmetic were not interned,
because they were not literals.

--
Neil Cerutti

Steve Holden

unread,
Aug 9, 2007, 4:38:18 PM8/9/07
to pytho...@python.org
kyos...@gmail.com wrote:
[...]

>
> Steve,
>
> I thought you'd probably weigh in on this esoteric matter. Very
> illuminating, as usual.
>
Thank you!

Grzegorz Słodkowicz

unread,
Aug 9, 2007, 4:50:16 PM8/9/07
to pytho...@python.org
>
> Why? Because.
>
> Seriously, it's just an optimization by the implementers. There is no
> need for more than one empty tuple, since tuples can never be modified
> once created.
>
> But they decided not to create (1, ) in advance. They probably knew that
> hardly anybody would want to create that tuple ;-) [Seriously: if you
> started trying to predict which tuples would be used you would go
> insane, but the empty tuple is the most likely candidate].
>
That's just theorisation but I'd rather expect the interpreter simply
not to create a second tuple while there already is an identical one.
This could save some memory if the tuple was large (Although by the same
token comparison of large tuples can be expensive). Admittedly the empty
tuple is a special case but then 'Special cases aren't special enough to
break the rules'.

A bit odd.

Best regards,
Greg

Erik Max Francis

unread,
Aug 9, 2007, 5:24:42 PM8/9/07
to
John K Masters wrote:

> OK fiddling around with this and reading the docs I tried:-
> a = 'qqqqqqqqqq' #10 q's
> b = 'qqqqqqqqqq' #10 q's
> a is b
> true
> c = 'q' * 10
> c
> 'qqqqqqqqqq' #10 q's
> d = 'q' * 10
> d
> 'qqqqqqqqqq' #10 q's
> c is d
> false
>
> So from what I've read "==" tests for equivalence, "is" tests for identity but
> that does not explain the behaviour above.

Using the `is` test between non-sentinel immutable objects (e.g.,
integers, floats, strings) is _completely pointless_. Since immutable
objects cannot be changed, it is up to the interpreter (and thus can
vary from version to version and implementation to implementation)
whether or not to "cache" the objects and reuse them, or whether or not
to create new ones. You should never be testing such objects for
identity (`is`); you should only be testing them for equality (`==`).

The only time it makes sense to use the `is` operator with immutable
objects is when you're dealing with a sentinel object, e.g., `None`, or
a custom sentinel object (e.g., `mySentinel = object()`), because that
is the only time you actually _are_ interested in identity. All other
times you are not really interested in identity.

Sample code as above is essentially showing unimportant implementation
details that should never concern you. Don't use `is`, use `==`.

--
Erik Max Francis && m...@alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 20 N 121 53 W && AIM, Y!M erikmaxfrancis
Chance favors the trained mind.
-- Louis Pasteur

Erik Max Francis

unread,
Aug 9, 2007, 5:25:35 PM8/9/07
to
Grzegorz Słodkowicz wrote:

> That's just theorisation but I'd rather expect the interpreter simply
> not to create a second tuple while there already is an identical one.
> This could save some memory if the tuple was large (Although by the same
> token comparison of large tuples can be expensive). Admittedly the empty
> tuple is a special case but then 'Special cases aren't special enough to
> break the rules'.
>
> A bit odd.

It doesn't save time if you have to check through all the existing
tuples for matches ...

Hrvoje Niksic

unread,
Aug 9, 2007, 5:55:27 PM8/9/07
to
Grzegorz Słodkowicz <jer...@wp.pl> writes:

>> Seriously, it's just an optimization by the implementers. There is
>> no need for more than one empty tuple, since tuples can never be
>> modified once created.
>>
>> But they decided not to create (1, ) in advance. They probably knew
>> that hardly anybody would want to create that tuple ;-) [Seriously:
>> if you started trying to predict which tuples would be used you
>> would go insane, but the empty tuple is the most likely candidate].
>>
> That's just theorisation but I'd rather expect the interpreter simply
> not to create a second tuple while there already is an identical
> one.

But then tuple creation would be slowed down by searching for whether
an "identical one" already exists. In the general case, that is quite
unlikely, so it's not done. (I suspect that only the requirement to
store the list of all tuples somewhere would outweigh any potential
gains of this strategy; and if the search were implemented as a hash
table lookup, even more space would be wasted.) It's done for the
empty tuple because no search is necessary, only a size test.

> Admittedly the empty tuple is a special case but then 'Special cases
> aren't special enough to break the rules'.

Except no rule is being broken. As others have pointed out, since
tuples are immutable, caching them is quite safe.

Steve Holden

unread,
Aug 9, 2007, 6:10:43 PM8/9/07
to pytho...@python.org
Grzegorz Słodkowicz wrote:
>> Why? Because.

>>
>> Seriously, it's just an optimization by the implementers. There is no
>> need for more than one empty tuple, since tuples can never be modified
>> once created.
>>
>> But they decided not to create (1, ) in advance. They probably knew that
>> hardly anybody would want to create that tuple ;-) [Seriously: if you
>> started trying to predict which tuples would be used you would go
>> insane, but the empty tuple is the most likely candidate].
>>
> That's just theorisation but I'd rather expect the interpreter simply
> not to create a second tuple while there already is an identical one.
> This could save some memory if the tuple was large (Although by the same
> token comparison of large tuples can be expensive). Admittedly the empty
> tuple is a special case but then 'Special cases aren't special enough to
> break the rules'.
>
> A bit odd.
>
It's a trade-off, preferring to optimize time rather than memory usage.
If tuples were "interned" like some strings then tuple creation would be
more expensive due to the need to search the cache when creating them
which, as you rightly point out, could be very expensive for large tuples.

The integers under 100 are also, IIRC, special-cased:

>>> x = 12
>>> y = 32676
>>> x is 12
True
>>> y is 32676
False
>>>

I guess if you *make* the rules you can decide when it's reasonable to
break them!

Ben Finney

unread,
Aug 9, 2007, 9:13:39 PM8/9/07
to
Grzegorz Słodkowicz <jer...@wp.pl> writes:

> That's just theorisation but I'd rather expect the interpreter
> simply not to create a second tuple while there already is an
> identical one.

Others have already said that it's an implementation optimisation,
which seems to partly answer your question.

It's important to also realise that the language is *deliberately*
non-committal on whether any given value will have this behaviour;
that is, it's entirely left to the language implementation which
optimisation trade-offs to make, and the language user (that's you and
I) should *not* expect any particular behaviour to hold between
different implementations.

--
\ "Holy priceless collection of Etruscan snoods, Batman!" -- |
`\ Robin |
_o__) |
Ben Finney

Erik Max Francis

unread,
Aug 9, 2007, 11:57:49 PM8/9/07
to
Ben Finney wrote:

> It's important to also realise that the language is *deliberately*
> non-committal on whether any given value will have this behaviour;
> that is, it's entirely left to the language implementation which
> optimisation trade-offs to make, and the language user (that's you and
> I) should *not* expect any particular behaviour to hold between
> different implementations.

Right. In the terminology of language standards, it is implementation
defined.

--
Erik Max Francis && m...@alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 20 N 121 53 W && AIM, Y!M erikmaxfrancis

Only love is worth the risk
-- Oleta Adams

Paul Rudin

unread,
Aug 10, 2007, 12:41:27 AM8/10/07
to
John K Masters <johnm...@oxtedonline.net> writes:

>
> OK fiddling around with this and reading the docs I tried:-
> a = 'qqqqqqqqqq' #10 q's
> b = 'qqqqqqqqqq' #10 q's
> a is b
> true
> c = 'q' * 10
> c
> 'qqqqqqqqqq' #10 q's
> d = 'q' * 10
> d
> 'qqqqqqqqqq' #10 q's
> c is d
> false
>
> So from what I've read "==" tests for equivalence, "is" tests for identity but
> that does not explain the behaviour above.
>

There's nothing especially to be explained, other than "that's the way
the compiler does it". Two equal string literals might be the same
object or they might not be. It's a language implementation detail.

Dick Moores

unread,
Aug 10, 2007, 1:57:22 PM8/10/07
to Ben Finney, pytho...@python.org
At 06:13 PM 8/9/2007, Ben Finney wrote:
>Content-Transfer-Encoding: base64Grzegorz
>SÅ‚odkowicz <jer...@wp.plÜš]\΂‚ ˆ] ÜÈ @st
>theorisation but I'd rather expect the interpreter
> > simply not to create a second tuple while there already is an
> > identical one.
>
>Others have already said that it's an implementation optimisation,
>which seems to partly answer your question.
>
>It's important to also realise that the language is *deliberately*
>non-committal on whether any given value will have this behaviour;
>that is, it's entirely left to the language implementation which
>optimisation trade-offs to make, and the language user (that's you and
>I) should *not* expect any particular behaviour to hold between
>different implementations.

I'm not clear on the meaning of "implementations"
here. Would 2.5 for Windows, Mac, Linux all be
different implementations? Would Iron Python be another? ActivePython?

Thanks,

Dick


Marc 'BlackJack' Rintsch

unread,
Aug 10, 2007, 2:21:55 PM8/10/07
to

Taken to the extreme you shouldn't rely on implementation details at all,
so even the very same interpreter might cache and reuse the empty tuple in
one run but not in the next.

For me CPython, Iron Python and Jython are different implementations as
they are all written from scratch.

Ciao,
Marc 'BlackJack' Rintsch

Trent Mick

unread,
Aug 10, 2007, 2:40:40 PM8/10/07
to Dick Moores, pytho...@python.org, Ben Finney
Dick Moores wrote:
> At 06:13 PM 8/9/2007, Ben Finney wrote:
>> It's important to also realise that the language is *deliberately*
>> non-committal on whether any given value will have this behaviour;
>> that is, it's entirely left to the language implementation which
>> optimisation trade-offs to make, and the language user (that's you and
>> I) should *not* expect any particular behaviour to hold between
>> different implementations.
>
> I'm not clear on the meaning of "implementations"
> here. Would 2.5 for Windows, Mac, Linux all be
> different implementations? Would Iron Python be another? ActivePython?

(Note that I'm jumping into this without having read the thread, so
apologies if I didn't grasp the question in its proper context.)

Separate Python "implementations" generally refers to a separate source
code base for that Python build. According to that definition, current
examples of Python implementations are: CPython (from python.org,
C-based), Jython (Java-based), Stackless Python (I'm not that familiar
to how much of the CPython source code, if any, Stackless borrows),
IronPython (.NET/C#-based), possibly PyPy (Python-based, I'm not that
familiar with it). Also eventually interesting might be the recently
announced IronMonkey (http://wiki.mozilla.org/Tamarin:IronMonkey).

Windows, Mac, Linux, etc. installations/builds/installers of a
particular implementation would be different platform *builds* (my
language).

ActivePython is a separate (from python.org's) *distribution* of CPython
-- i.e. the sample implementation as CPython (same source code). This is
similar, in some respects, to SuSE, Debian, RedHat, Ubuntu, etc. being
different distributions of Linux.


Trent

--
Trent Mick
trentm at activestate.com

Ben Finney

unread,
Aug 12, 2007, 5:41:03 AM8/12/07
to
Dick Moores <r...@rcblue.com> writes:

For the purpose of the above statement, you should consider even the
same Python on two different machines to be "different
implementations". As a programmer writing Python code, you should not
expect any "implementation-dependent" behaviour to operate in any
particular way.

--
\ "The fact that a believer is happier than a skeptic is no more |
`\ to the point than the fact that a drunken man is happier than a |
_o__) sober one." —George Bernard Shaw |
Ben Finney

Steve Holden

unread,
Aug 12, 2007, 11:23:26 AM8/12/07
to pytho...@python.org
Dick Moores wrote:
> On 8/12/07, *Ben Finney* <bignose+h...@benfinney.id.au
> <mailto:bignose+h...@benfinney.id.au>> wrote:

>
> Dick Moores <r...@rcblue.com <mailto:r...@rcblue.com>> writes:
>
> > At 06:13 PM 8/9/2007, Ben Finney wrote:
> > >it's entirely left to the language implementation which
> > >optimisation trade-offs to make, and the language user (that's you
> > >and I) should *not* expect any particular behaviour to hold between
> > >different implementations.
> >
> > I'm not clear on the meaning of "implementations" here. Would 2.5
> > for Windows, Mac, Linux all be different implementations? Would Iron
> > Python be another? ActivePython?
>
> For the purpose of the above statement, you should consider even the
> same Python on two different machines to be "different
> implementations". As a programmer writing Python code, you should not
> expect any "implementation-dependent" behaviour to operate in any
> particular way.
>
>
> So would a programmer EVER use "is" in a script?

Sure. For example, the canonical test for None uses

x is None

because there is only ever one instance of type Nonetype, so it's the
fastest test. Generally speaking you use "is" to test for identity (do
these two expressions reference the same object) rather than equality
(do these two expressions evaluate to equivalent objects).

Dick Moores

unread,
Aug 12, 2007, 12:34:42 PM8/12/07
to Steve Holden, pytho...@python.org
At 08:23 AM 8/12/2007, Steve Holden wrote:
>Dick Moores wrote:
> > So would a programmer EVER use "is" in a script?
>
>Sure. For example, the canonical test for None uses
>
> x is None
>
>because there is only ever one instance of type Nonetype, so it's the
>fastest test. Generally speaking you use "is" to test for identity (do
>these two expressions reference the same object) rather than equality
>(do these two expressions evaluate to equivalent objects).

Off the top of your head, could you or others give me as many
examples as you can think of?

Thanks again,

Dick


Steve Holden

unread,
Aug 12, 2007, 12:59:59 PM8/12/07
to pytho...@python.org
Occasionally it's necessary to test for a specific type (though in
Python this is usually bad practice). Since types are also singletons
the best way to do this is (e.g.):

type(x) is type([]) # test specifically for a list

If you want to know whether you have been told to write to standard
output, one possible test is

if f is not sys.stdout

Similarly, of course, you can test for the other standard IO channels.

The imputil module contains the test

if importer is not self

to determine whether a reload() should be performed in the context of
the current package.

When you need to establish a specific sentinel value that can never be
provided by an outside caller it's normal to create an instance of
object (the simplest possible thing you can create in a Python program)
and test for that instance, as in

sentinel = object()
...
if value is sentinel:

You can test whether a class is new-style as opposed to old-style, which
can help to unify old-style and new-style objects:

class MetaProperty(type):
def __new__(cls, name, bases, dct):
if bases[0] is object: # allow us to create class Property
return type.__new__(cls, name, bases, dct)
return property(dct.get('get'), dct.get('set'),
dct.get('delete'), dct.get('__doc__'))

def __init__(cls, name, bases, dct):
if bases[0] is object:
return type.__init__(cls, name, bases, dct)


That gets you started ...

Dick Moores

unread,
Aug 12, 2007, 1:22:51 PM8/12/07
to Steve Holden, pytho...@python.org

Sure does. Thanks very much, Steve.

Dick


0 new messages