Run the following Python statements and briefly explain why you get the behavior displayed by the print
functions.
a = 5
b = a
print (id(a), id(b))
c = b
b = 3
print (a,b,c)
print (id(a),id(b),id(c))
b = a
b = 5
print (id(a), id(b))
a = [5]
b = a
print (id(a), id(b))
b.append(1)
print (a,b)
print (id(a),id(b))
a = [5]
b = list(a)
print (a,b)
print (id(a), id(b))
b = a[:]
print (a,b)
print (id(a), id(b))
a = (5,)
b = tuple(a)
print (id(a), id(b))
b = a[:]
print (id(a), id(b))
# Assign a value to a new variable
a = 5
# Create an alias identifier for this variable
b = a
# Observe how they refer to the same variable!
print (id(a), id(b))
# Create another alias
c = b
# Now assign a new value to b!
b = 3
# And observe how a and c are still the same variable
# But b is not
print (a,b,c)
print (id(a),id(b),id(c))
# Now for another quirk, suppose we do this:
b = a
b = 5
# We used an assignment, but the value didn't change
# So the alias remains unbroken
print (id(a), id(b))
# Create a new <list>
a = [5]
# Create an alias identifier for this list
b = a
print (id(a), id(b))
# Now change the <list> b in-place
b.append(1)
# And observe how this also changes a
# The alias is not broken by in-place operations
print (a,b)
print (id(a),id(b))
# Create a <list>
a = [5]
# Create a new <list> with the same value
b = list(a)
# We now have two separate variables with identical but separate values
print (a,b)
print (id(a), id(b))
# Same with the full slice technique:
b = a[:]
print (a,b)
print (id(a), id(b))
# Create <tuple>
a = (5,)
# Try to force a copy
b = tuple(a)
# It didn't work...
print (id(a), id(b))
# Neither does this
b = a[:]
print (id(a), id(b))