Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #86139 > unrolled thread

id() and is operator

Started byLJ <luisjosenovoa@gmail.com>
First post2015-02-22 09:53 -0800
Last post2015-02-23 01:14 -0500
Articles 12 — 7 participants

Back to article view | Back to comp.lang.python


Contents

  id() and is operator LJ <luisjosenovoa@gmail.com> - 2015-02-22 09:53 -0800
    Re: id() and is operator Laura Creighton <lac@openend.se> - 2015-02-22 19:13 +0100
    Re: id() and is operator Chris Angelico <rosuav@gmail.com> - 2015-02-23 06:23 +1100
    Re: id() and is operator Gary Herron <gherron@digipen.edu> - 2015-02-22 11:16 -0800
    Re: id() and is operator Laura Creighton <lac@openend.se> - 2015-02-22 20:58 +0100
    Re: id() and is operator Marko Rauhamaa <marko@pacujo.net> - 2015-02-22 23:25 +0200
      Re: id() and is operator Chris Angelico <rosuav@gmail.com> - 2015-02-23 08:36 +1100
      Re: id() and is operator Terry Reedy <tjreedy@udel.edu> - 2015-02-23 01:02 -0500
        Re: id() and is operator Marko Rauhamaa <marko@pacujo.net> - 2015-02-23 08:31 +0200
      Re: id() and is operator Gary Herron <gherron@digipen.edu> - 2015-02-22 22:29 -0800
    Re: id() and is operator Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-02-23 12:31 +1100
    Re: id() and is operator Terry Reedy <tjreedy@udel.edu> - 2015-02-23 01:14 -0500

#86139 — id() and is operator

FromLJ <luisjosenovoa@gmail.com>
Date2015-02-22 09:53 -0800
Subjectid() and is operator
Message-ID<87f18c68-120d-44f2-bd34-6f73c69365da@googlegroups.com>
Hi everyone. Quick question here. Lets suppose if have the following numpy array:

b=np.array([[0]*2]*3)

and then:

>>> id(b[0])
45855552
>>> id(b[1])
45857512
>>> id(b[2])
45855552

Please correct me if I am wrong, but according to this b[2] and b[0] are the same object. Now,

>>> b[0] is b[2]
False


Any clarification is much appreciated.

Cheers,

[toc] | [next] | [standalone]


#86140

FromLaura Creighton <lac@openend.se>
Date2015-02-22 19:13 +0100
Message-ID<mailman.19019.1424628820.18130.python-list@python.org>
In reply to#86139
In a message of Sun, 22 Feb 2015 09:53:33 -0800, LJ writes:
>Hi everyone. Quick question here. Lets suppose if have the following numpy array:
>
>b=np.array([[0]*2]*3)
>
>and then:
>
>>>> id(b[0])
>45855552
>>>> id(b[1])
>45857512
>>>> id(b[2])
>45855552
>
>Please correct me if I am wrong, but according to this b[2] and b[0] are the same object. Now,
>
>>>> b[0] is b[2]
>False


You are running into one of the peculiarities of the python representation
of numbers.  It can make things more efficient to represent all common
numbers as 'there is only one' of them.

So.

  Python 2.7.9 (default, Dec 11 2014, 08:58:12)
 [GCC 4.9.2] on linux2
 Type "help", "copyright", "credits" or "license" for more information.
 >>> a = 1
 >>> b = 1
 >>> a is b
 True
 >>> a = 1001
 >>> b = 1001
 >>> a is b
 False

--------
Don't rely on this.  Other implementations are free to implement this
however they like.
--------

[PyPy 2.4.0 with GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>> a = 1001
>>>> b = 1001
>>>> a is b
True

Laura

[toc] | [prev] | [next] | [standalone]


#86148

FromChris Angelico <rosuav@gmail.com>
Date2015-02-23 06:23 +1100
Message-ID<mailman.19023.1424633042.18130.python-list@python.org>
In reply to#86139
On Mon, Feb 23, 2015 at 5:13 AM, Laura Creighton <lac@openend.se> wrote:
> In a message of Sun, 22 Feb 2015 09:53:33 -0800, LJ writes:
>>Hi everyone. Quick question here. Lets suppose if have the following numpy array:
>>
>>b=np.array([[0]*2]*3)
>>
>>and then:
>>
>>>>> id(b[0])
>>45855552
>>>>> id(b[1])
>>45857512
>>>>> id(b[2])
>>45855552
>>
>>Please correct me if I am wrong, but according to this b[2] and b[0] are the same object. Now,
>>
>>>>> b[0] is b[2]
>>False
>
>
> You are running into one of the peculiarities of the python representation
> of numbers.  It can make things more efficient to represent all common
> numbers as 'there is only one' of them.

That shouldn't break the correspondence between id() and the is
operator. The id function is documented as returning an integer which
is "guaranteed to be unique among simultaneously existing objects",
and if all three elements of b exist through the entire duration of
this experiment, it should be perfectly safe to compare their id()s to
check object identity.

So the only explanation I can think of is: When you subscript a numpy
array, you aren't getting back a reference to a pre-existing object,
but you are instead getting a brand new object which is being created
for you. (This theory is supported by a vague recollection that
subscripting a numpy array returns a view of some sort, but you'd have
to check the docs.) If that theory is correct, then you'd expect to
find that the id() of such a thing is not stable; and that is, in
fact, what I see:

>>> import numpy as np
>>> b=np.array([[0]*2]*3)
>>> id(b[0])
26806960
>>> id(b[0])
26655344
>>> id(b[0])
26820432
>>> id(b[0])
26806960
>>> id(b[0])
26655344

After a few iterations, they're getting reused, but it's not like
playing with a Python list, where you would be getting back the exact
same object every time

You'd have to check the docs to be sure, but this is how I would go
about exploring the situation.

ChrisA

[toc] | [prev] | [next] | [standalone]


#86149

FromGary Herron <gherron@digipen.edu>
Date2015-02-22 11:16 -0800
Message-ID<mailman.19024.1424633079.18130.python-list@python.org>
In reply to#86139
On 02/22/2015 09:53 AM, LJ wrote:
> Hi everyone. Quick question here. Lets suppose if have the following numpy array:
>
> b=np.array([[0]*2]*3)
>
> and then:
>
>>>> id(b[0])
> 45855552
>>>> id(b[1])
> 45857512
>>>> id(b[2])
> 45855552
>
> Please correct me if I am wrong, but according to this b[2] and b[0] are the same object. Now,
>
>>>> b[0] is b[2]
> False
>
>
> Any clarification is much appreciated.
>
> Cheers,


In fact, b[0] and b[2] are different objects as can be seen here:
 >>> import numpy as np
 >>> b=np.array([[0]*2]*3)
 >>> b[0]=1 // broadcast into both ints in row 0
 >>> b[1]=2 // ... row 1
 >>> b[2]=3 // ... row 2
 >>> b
array([[1, 1],
        [2, 2],
        [3, 3]])

When you extracted b[0], you got a newly created python/numpy object 
(1x2 array of ints) briefly stored at location  45855552 but then 
deleted immediately after that use.  A little later, the extraction of 
b[2] used the same bit of memory.  The id of a temporarily created value 
is meaningless, and apparently misleading.

As a separate issue, each of b, b[0], b[1], and b[2] do *all* refer to 
the same underlying array of ints as can be seen here:
 >>> r = b[0]
 >>> r[0] = 123
 >>> b
array([[123,   1],
        [  2,   2],
        [  3,   3]])


but the Python/numpy objects that wrap portions of that underlying array 
of ints are all distinct.


Gary Herron



-- 
Dr. Gary Herron
Department of Computer Science
DigiPen Institute of Technology
(425) 895-4418

[toc] | [prev] | [next] | [standalone]


#86152

FromLaura Creighton <lac@openend.se>
Date2015-02-22 20:58 +0100
Message-ID<mailman.19027.1424635097.18130.python-list@python.org>
In reply to#86139
Ooops, I missed the numpy, so I thought that it was the contents
of the array that was causing the problem.  My very bad.  Apologies.

Laura

[toc] | [prev] | [next] | [standalone]


#86157

FromMarko Rauhamaa <marko@pacujo.net>
Date2015-02-22 23:25 +0200
Message-ID<871tlhiqpz.fsf@elektro.pacujo.net>
In reply to#86139
LJ <luisjosenovoa@gmail.com>:

>>>> id(b[0])
> 45855552
[...]
>>>> id(b[2])
> 45855552
>
> Please correct me if I am wrong, but according to this b[2] and b[0]
> are the same object. Now,
>
>>>> b[0] is b[2]
> False

This is a true statement:

   If X is Y, then id(X) == id(Y).

However, this is generally not a true statement:

   If X is Y, then id(X) is id(Y).


Marko

[toc] | [prev] | [next] | [standalone]


#86159

FromChris Angelico <rosuav@gmail.com>
Date2015-02-23 08:36 +1100
Message-ID<mailman.19030.1424640985.18130.python-list@python.org>
In reply to#86157
On Mon, Feb 23, 2015 at 8:25 AM, Marko Rauhamaa <marko@pacujo.net> wrote:
> This is a true statement:
>
>    If X is Y, then id(X) == id(Y).
>
> However, this is generally not a true statement:
>
>    If X is Y, then id(X) is id(Y).

Irrelevant, because the identities of equal integers didn't come into this.

ChrisA

[toc] | [prev] | [next] | [standalone]


#86192

FromTerry Reedy <tjreedy@udel.edu>
Date2015-02-23 01:02 -0500
Message-ID<mailman.19053.1424671345.18130.python-list@python.org>
In reply to#86157
On 2/22/2015 4:25 PM, Marko Rauhamaa wrote:
> LJ <luisjosenovoa@gmail.com>:
>
>>>>> id(b[0])
>> 45855552
> [...]
>>>>> id(b[2])
>> 45855552

>> Please correct me if I am wrong, but according to this b[2] and b[0]
>> are the same object. Now,
>>
>>>>> b[0] is b[2]
>> False
>
> This is a true statement:
>
>     If X is Y, then id(X) == id(Y).
>
> However, this is generally not a true statement:
>
>     If X is Y, then id(X) is id(Y).

If X and Y exist at the *same time*, then (X is Y) == (id(X) is id(Y)). 
  Since X and Y in the example above do not exist at the same time, it 
is nonsensical to compare them.

-- 
Terry Jan Reedy

[toc] | [prev] | [next] | [standalone]


#86196

FromMarko Rauhamaa <marko@pacujo.net>
Date2015-02-23 08:31 +0200
Message-ID<87k2z9gmvr.fsf@elektro.pacujo.net>
In reply to#86192
Terry Reedy <tjreedy@udel.edu>:

> On 2/22/2015 4:25 PM, Marko Rauhamaa wrote:
>> This is a true statement:
>>
>>     If X is Y, then id(X) == id(Y).
>>
>> However, this is generally not a true statement:
>>
>>     If X is Y, then id(X) is id(Y).
>
> If X and Y exist at the *same time*, then (X is Y) == (id(X) is id(Y)).

Sorry, you're wrong:

   Python 3.3.2 (default, Dec  4 2014, 12:49:00) 
   [GCC 4.8.3 20140911 (Red Hat 4.8.3-7)] on linux
   Type "help", "copyright", "credits" or "license" for more information.
   >>> x = "alksjdlfkajsf"
   >>> id(x) is id(x)
   False
   >>> (x is x) == (id(x) is id(x))
   False


Marko

[toc] | [prev] | [next] | [standalone]


#86195

FromGary Herron <gherron@digipen.edu>
Date2015-02-22 22:29 -0800
Message-ID<mailman.19055.1424672996.18130.python-list@python.org>
In reply to#86157
On 02/22/2015 10:02 PM, Terry Reedy wrote:
> On 2/22/2015 4:25 PM, Marko Rauhamaa wrote:
>> LJ <luisjosenovoa@gmail.com>:
>>
>>>>>> id(b[0])
>>> 45855552
>> [...]
>>>>>> id(b[2])
>>> 45855552
>
>>> Please correct me if I am wrong, but according to this b[2] and b[0]
>>> are the same object. Now,
>>>
>>>>>> b[0] is b[2]
>>> False
>>
>> This is a true statement:
>>
>>     If X is Y, then id(X) == id(Y).
>>
>> However, this is generally not a true statement:
>>
>>     If X is Y, then id(X) is id(Y).
>
> If X and Y exist at the *same time*, then (X is Y) == (id(X) is 
> id(Y)).  Since X and Y in the example above do not exist at the same 
> time, it is nonsensical to compare them.

Not quite.  You've been bitten by the "is" versus "==" trap.   You could use
     id(X)==id(Y)
but not
     id(X) is id(Y)
not even if X and Y are the same object.   Simple examples:

 >>> a=3
 >>> id(a) is id(a)
False

 >>> a=3
 >>> b=a
 >>> id(a) is id(b)
False

The explanation is that each call to id() makes its own independent 
Python integer object containing the large integer (10771264 in this 
case).  The two integer objects satisfy "==", but they are separate 
Python objects so they do not satisfy "is".

As a side note,  It is an implementation detail whether two Python 
integer objects created independently but with the same value are 
separate objects or references to a single object.   CPython caches 
small integers so that only one integer object of each value exists, but 
not so for large integers.  You can experiment with the cutoff on your 
particular flavor of Python.  On mine (Python 3.4.2 (default, Oct  8 
2014, 13:08:17) ;[GCC 4.9.1] on linux)
it's somewhere between 200 and 300:

 >>> 201 is 1+200
True
 >>> 301 is 1+300
False

Gary Herron







-- 
Dr. Gary Herron
Department of Computer Science
DigiPen Institute of Technology
(425) 895-4418

[toc] | [prev] | [next] | [standalone]


#86175

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2015-02-23 12:31 +1100
Message-ID<54ea82ef$0$13003$c3e8da3$5496439d@news.astraweb.com>
In reply to#86139
LJ wrote:

> Hi everyone. Quick question here. Lets suppose if have the following numpy
> array:
> 
> b=np.array([[0]*2]*3)
> 
> and then:
> 
>>>> id(b[0])
> 45855552
>>>> id(b[1])
> 45857512
>>>> id(b[2])
> 45855552
> 
> Please correct me if I am wrong, but according to this b[2] and b[0] are
> the same object. 

Not necessarily. CPython (the version of Python you are using) can reuse
object IDs. This is not the case for all Pythons, e.g. Jython and
IronPython never reuse IDs. That means that if you compare the ID of two
objects in CPython which are not alive at the same time, they might have
received the same ID.

py> id("hello world")
3083591616
py> id("now what???")
3083591616

IDs are only unique if the objects are alive at the same time.

Numpy arrays are effectively C arrays of low-level machine values, what Java
calls "unboxed" values. So when you index a specific value, Python has to
create a new object to hold it. (In this case, that object is also an
array.) If that object is then garbage collected, the next time you ask for
the value at an index, the freshly created object may end up with the same
ID just by chance.

py> import numpy as np
py> b = np.array([[0]*2]*3)
py> x = b[0]
py> y = b[1]
py> print id(x), id(y)
155749968 156001664
py> print id(b[0]), id(b[1])  # temporary objects that are thrown away
156055016 156055016


If you try it yourself, you may or may not get exactly the same results. You
may need to print the IDs repeatedly until, just by chance, you end up with
identical IDs.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#86194

FromTerry Reedy <tjreedy@udel.edu>
Date2015-02-23 01:14 -0500
Message-ID<mailman.19054.1424672057.18130.python-list@python.org>
In reply to#86139
On 2/22/2015 12:53 PM, LJ wrote:
> Hi everyone. Quick question here. Lets suppose if have the
> following numpy array:

> b=np.array([[0]*2]*3)
>
> and then:
>
>>>> id(b[0])
> 45855552
>>>> id(b[1])
> 45857512
>>>> id(b[2])
> 45855552
>
> Please correct me if I am wrong,

You are, as other explained
 > but according to this b[2] and b[0] are the same object.
>>>> b[0] is b[2]
> False
>
> Any clarification is much appreciated.

In Python, 'two' objects can only be the same thing if they exist 
simultaneously.  Retry your experiment with simultaneous objects.

 >>> b0 = b[0]
 >>> b1 = b[1]
 >>> b2 = b[2]  # etc.

The three objects will have different ids.  The mail purpose of the id 
function is to text properties of a particular implementation.  It also 
has uses with ctypes.  Beginners should generally ignore it, and 
certainly not touch it until reading and understanding its doc.  The 
main use for 'is' is for 'is None' comparison.

-- 
Terry Jan Reedy

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web