Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #86139 > unrolled thread
| Started by | LJ <luisjosenovoa@gmail.com> |
|---|---|
| First post | 2015-02-22 09:53 -0800 |
| Last post | 2015-02-23 01:14 -0500 |
| Articles | 12 — 7 participants |
Back to article view | Back to comp.lang.python
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
| From | LJ <luisjosenovoa@gmail.com> |
|---|---|
| Date | 2015-02-22 09:53 -0800 |
| Subject | id() 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]
| From | Laura Creighton <lac@openend.se> |
|---|---|
| Date | 2015-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]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-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]
| From | Gary Herron <gherron@digipen.edu> |
|---|---|
| Date | 2015-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]
| From | Laura Creighton <lac@openend.se> |
|---|---|
| Date | 2015-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]
| From | Marko Rauhamaa <marko@pacujo.net> |
|---|---|
| Date | 2015-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]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-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]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2015-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]
| From | Marko Rauhamaa <marko@pacujo.net> |
|---|---|
| Date | 2015-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]
| From | Gary Herron <gherron@digipen.edu> |
|---|---|
| Date | 2015-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]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2015-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]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2015-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