# Freezing a mutable (was Re: lambda)

Nick Coghlan ncoghlan at iinet.net.au
Thu Jan 20 05:08:05 EST 2005

```Antoon Pardon wrote:
> Interesting idea. But I think you are wrong when you say that two lists
> that compare equal at the time they are frozen, will get the same
> dictionary entry. The problem is an object must compare equal to
> the key in the dictionary to get at the same entry. So if you freeze
> a list and its copy but then mutate them differently, they no longer
> are equal and so wont get you at the same entry.

The trick is that the result of the freezing operation is cached until such time
as you explicitly unfreeze the object.

Output:

x: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
y: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Write via x, read via y: Hi there!
x: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y: [0, 1, 2, 3, 4, 5, 6, 7, 8]
Read via mutated x: Hi there!
Read via mutated y: Hi there!
x: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y: [0, 1, 2, 3, 4, 5, 6, 7, 8]
Found unfrozen x: False
Found unfrozen y: False

Produced by:

class mylist(list):
def __init__(self, arg):
super(mylist, self).__init__(arg)
self._tuple = None
def frozen(self):
if self._tuple is None:
self._tuple = tuple(self)
return self._tuple
def unfreeze(self):
self._tuple = None

x = mylist(range(10))
y = mylist(range(10))
dct = {}
dct[x.frozen()] = "Hi there!"
print "x:", x
print "y:", y
print "Write via x, read via y:", dct[y.frozen()]
x.append(10)
del y[-1]
print "x:", x
print "y:", y
print "Read via mutated x:", dct[x.frozen()]
print "Read via mutated y:", dct[y.frozen()]
x.unfreeze()
y.unfreeze()
print "x:", x
print "y:", y
print "Found unfrozen x:", x.frozen() in dct
print "Found unfrozen y:", y.frozen() in dct

--
Nick Coghlan   |   ncoghlan at email.com   |   Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net

```