id() trickery
Author Message id() trickery

Well, I've broken my brain again.  Could someone explain this to me?

Quote:
>>> a = id(1)
>>> a, id(1)
(732968, 732968)
>>> b = id(1)
>>> b, id(1)
(732968, 732968)
>>> a,b,id(a),id(b)

(732968, 732968, 732236, 732212)
Quote:
>>> a = b + 0
>>> a,b,id(a),id(b)

(732968, 732968, 732188, 732212)
Quote:
>>> a = b
>>> a,b,id(a),id(b)

(732968, 732968, 732212, 732212)
Quote:
>>> a = b + 0
>>> a,b,id(a),id(b)

(732968, 732968, 732188, 732212)

Could someone tell me why the value returned by id(), which is just an
int, says type(), is acting a little fruity for me?  If a and b hold the
same integer, shouldn't they have the same value for id()?  And why do

Quote:
>>> a = b # and
>>> a = b + 0

have two different effects?

--

http://www.*-*-*.com/ ~japhy/                   http://www.*-*-*.com/
PerlMonth - An Online Perl Magazine             http://www.*-*-*.com/
The Perl Archive - Articles, Forums, etc.     http://www.*-*-*.com/

Wed, 04 Sep 2002 03:00:00 GMT  id() trickery
In article

Quote:

> Well, I've broken my brain again.  Could someone explain this to me?

> >>> a = id(1)
> >>> a, id(1)
> (732968, 732968)
> >>> b = id(1)
> >>> b, id(1)
> (732968, 732968)
> >>> a,b,id(a),id(b)
> (732968, 732968, 732236, 732212)
> >>> a = b + 0
> >>> a,b,id(a),id(b)
> (732968, 732968, 732188, 732212)
> >>> a = b
> >>> a,b,id(a),id(b)
> (732968, 732968, 732212, 732212)
> >>> a = b + 0
> >>> a,b,id(a),id(b)
> (732968, 732968, 732188, 732212)

> Could someone tell me why the value returned by id(), which is just an
> int, says type(), is acting a little fruity for me?  If a and b hold the
> same integer, shouldn't they have the same value for id()?  And why do

> >>> a = b # and
> >>> a = b + 0

> have two different effects?

I'd hazard a guess. if a = b then they both point to the same address.
Makes sense since this is a simple direct assignment. Now, if you do a =
b + 0, what the interpreter will do is perform the operation b + 0 and
store this in a temporary integer and then assign the the address of the
temporary integer to a; thus you would have two different addresses.

I think.

Wed, 04 Sep 2002 03:00:00 GMT  id() trickery

Quote:

> Well, I've broken my brain again.  Could someone explain this to me?

>>>> a = id(1)
>>>> a, id(1)
> (732968, 732968)
>>>> b = id(1)
>>>> b, id(1)
> (732968, 732968)
>>>> a,b,id(a),id(b)
> (732968, 732968, 732236, 732212)
>>>> a = b + 0
>>>> a,b,id(a),id(b)
> (732968, 732968, 732188, 732212)
>>>> a = b
>>>> a,b,id(a),id(b)
> (732968, 732968, 732212, 732212)
>>>> a = b + 0
>>>> a,b,id(a),id(b)
> (732968, 732968, 732188, 732212)

> Could someone tell me why the value returned by id(), which is just an
> int, says type(), is acting a little fruity for me?  If a and b hold the
> same integer, shouldn't they have the same value for id()?

No. That's not a requirement in the python object model. The identity of
an object and the value of an object are distinct.

If you're looking for a number which will be equal among objects which
are equal (not identical), you might want to look into the hash
function. Assuming hash is defined,

hash(a) == hash(b)    if and only if    a == b

hash has the additional constraint that its value may never change for
the lifetime of the object. This restricts its use to objects whose
object value is immutable relative to ==, < and >.

Quote:
> And why do

>>>> a = b # and
>>>> a = b + 0

> have two different effects?

They don't. id() is not an actual method of an object. It's more like an
internal debugging facility. It's not guaranteed to parallel the object's
value as defined by hash, ==, <, etc., or any of the object's other
publicly defined interfaces.

If you're trying to test the "effect" of performing the operator +
with the operand 0 on an object, you've got to put your "blinders" on
and only see through the defined interface -- in this case, it's the
numeric interface, which includes hash and compare, but not id.

Internally, a particular object implementation may decide to intern (recycle)
objects some times and not others, or maybe never at all. In the case of
the integers, only the first 100 whole numbers are interned. That's purely
an implementation decision. When the users of the object look at it through
the public interface, they'll neither know nor care.

Wed, 04 Sep 2002 03:00:00 GMT  id() trickery

Quote:
> Could someone tell me why the value returned by id(), which is just an
> int, says type(), is acting a little fruity for me?  If a and b hold the
> same integer, shouldn't they have the same value for id()?  And why do

> >>> a = b # and
> >>> a = b + 0

> have two different effects?

Id() return something like the current address of an object.
a = b means that a and b are the same objects, if then you write
b = 100
print a, will print 100

a = b + 0, then the operation "+" return a new object changing the
name binding to "a"

Thu, 05 Sep 2002 03:00:00 GMT  id() trickery
[Eric Jacobs, among much fine advice, stumbles]

Quote:
> ...
> If you're looking for a number which will be equal among objects which
> are equal (not identical), you might want to look into the hash
> function. Assuming hash is defined,

> hash(a) == hash(b)    if and only if    a == b

That one only works one way:

a == b implies hash(a) == hash(b)

but the converse doesn't hold.  For brownie points, figure out the expected
number of iterations before this program produces some output:

import random
import sys

def drive():
hash2float = {}
_hash, _random = hash, random.random
for i in xrange(sys.maxint):
x = _random()
h = _hash(x)
if hash2float[h] != x:
print "collision on hash code", h, \
"%24.17g %24.17g" % (x, hash2float[h]), \
"at i =", i
break
else:
hash2float[h] = x

drive()

On a 32-bit machine, here's sample output from two different runs:

collision on hash code -1892459086      0.57216902940840741
0.19135372926869554 at i = 98506

collision on hash code -757800254      0.39944426781689946
0.72798761861358496 at i = 52767

you're-halfway-to-becoming-a-cryptographer<wink>-ly y'rs  - tim

Fri, 06 Sep 2002 03:00:00 GMT  id() trickery

Quote:

>but the converse doesn't hold.  For brownie points, figure out the expected
>number of iterations before this program produces some output:

Approximately 82,137.
For brownie points calculate the expected number of iterations before the
program produces some output if the check "if hash2float[h] != x" is
removed.

Reuben

Fri, 06 Sep 2002 03:00:00 GMT  id() trickery

Quote:

> Id() return something like the current address of an object.
> a = b means that a and b are the same objects, if then you write
> b = 100
> print a, will print 100

ehm. It would print 100, if 'b = 100' would modify the object b is
bound to.

Since 'b = 100' binds the name 'b' to a new object, 'a' is
not modified.

hth,
/steffen
--

Fri, 06 Sep 2002 03:00:00 GMT

 Page 1 of 1 [ 7 post ]

Relevant Pages