Z
zillow10
Hi all,
I've been playing around with the identity function id() for different
types of objects, and I think I understand its behaviour when it comes
to objects like lists and tuples in which case an assignment r2 = r1
(r1 refers to an existing object) creates an alias r2 that refers to
the same object as r1. In this case id(r1) == id(r2) (or, if you
like: r1 is r2). However for r1, r2 assigned as follows: r1 = [1, 2,
3] and r2 = [1, 2, 3], (r1 is r2) is False, even if r1==r2,
etc. ...this is all very well. Therefore, it seems that id(r) can be
interpreted as the address of the object that 'r' refers to.
My observations of its behaviour when comparing ints, floats and
strings have raised some questions in my mind, though. Consider the
following examples:
#########################################################################
# (1) turns out to be true
a = 10
b = 10
print a is b
# (2) turns out to be false
f = 10.0
g = 10.0
print f is g
# behaviour when a list or tuple contains the same elements ("same"
meaning same type and value):
# define the following function, that checks if all the elements in an
iterable object are equal:
def areAllElementsEqual(iterable):
return reduce(lambda x, y: x == y and x, iterable) != False
# (3) checking if ids of all list elements are the same for different
cases:
a = 3*[1]; areAllElementsEqual([id(i) for i in a]) # True
b = [1, 1, 1]; areAllElementsEqual([id(i) for i in b]) # True
f = 3*[1.0]; areAllElementsEqual([id(i) for i in f]) # True
g = [1.0, 1.0, 1.0]; areAllElementsEqual([id(i) for i in g]) # True
g1 = [1.0, 1.0, 0.5+0.5]; areAllElementsEqual([id(i) for i in g1]) #
False
# (4) two equal floats defined inside a function body behave
differently than case (1):
def func():
f = 10.0
g = 10.0
return f is g
print func() # True
######################################################
I didn't mention any examples with strings; they behaved like ints
with respect to their id properties for all the cases I tried.
While I have no particular qualms about the behaviour, I have the
following questions:
1) Which of the above behaviours are reliable? For example, does a1 =
a2 for ints and strings always imply that a1 is a2?
2) From the programmer's perspective, are ids of ints, floats and
string of any practical significance at all (since these types are
immutable)?
3) Does the behaviour of ids for lists and tuples of the same element
(of type int, string and sometimes even float), imply that the tuple a
= (1,) takes (nearly) the same storage space as a = 10000*(1,)? (What
about a list, where elements can be changed at will?)
Would appreciate your responses...
AK
I've been playing around with the identity function id() for different
types of objects, and I think I understand its behaviour when it comes
to objects like lists and tuples in which case an assignment r2 = r1
(r1 refers to an existing object) creates an alias r2 that refers to
the same object as r1. In this case id(r1) == id(r2) (or, if you
like: r1 is r2). However for r1, r2 assigned as follows: r1 = [1, 2,
3] and r2 = [1, 2, 3], (r1 is r2) is False, even if r1==r2,
etc. ...this is all very well. Therefore, it seems that id(r) can be
interpreted as the address of the object that 'r' refers to.
My observations of its behaviour when comparing ints, floats and
strings have raised some questions in my mind, though. Consider the
following examples:
#########################################################################
# (1) turns out to be true
a = 10
b = 10
print a is b
# (2) turns out to be false
f = 10.0
g = 10.0
print f is g
# behaviour when a list or tuple contains the same elements ("same"
meaning same type and value):
# define the following function, that checks if all the elements in an
iterable object are equal:
def areAllElementsEqual(iterable):
return reduce(lambda x, y: x == y and x, iterable) != False
# (3) checking if ids of all list elements are the same for different
cases:
a = 3*[1]; areAllElementsEqual([id(i) for i in a]) # True
b = [1, 1, 1]; areAllElementsEqual([id(i) for i in b]) # True
f = 3*[1.0]; areAllElementsEqual([id(i) for i in f]) # True
g = [1.0, 1.0, 1.0]; areAllElementsEqual([id(i) for i in g]) # True
g1 = [1.0, 1.0, 0.5+0.5]; areAllElementsEqual([id(i) for i in g1]) #
False
# (4) two equal floats defined inside a function body behave
differently than case (1):
def func():
f = 10.0
g = 10.0
return f is g
print func() # True
######################################################
I didn't mention any examples with strings; they behaved like ints
with respect to their id properties for all the cases I tried.
While I have no particular qualms about the behaviour, I have the
following questions:
1) Which of the above behaviours are reliable? For example, does a1 =
a2 for ints and strings always imply that a1 is a2?
2) From the programmer's perspective, are ids of ints, floats and
string of any practical significance at all (since these types are
immutable)?
3) Does the behaviour of ids for lists and tuples of the same element
(of type int, string and sometimes even float), imply that the tuple a
= (1,) takes (nearly) the same storage space as a = 10000*(1,)? (What
about a list, where elements can be changed at will?)
Would appreciate your responses...
AK