0

I have a data structure which consists of lists, ints and strings, nested arbitarily. For example:

[ "data", [ 1, "file", [], [1,2] ], 3 ]

I want to index a dict using objects like this, but I can't because python complains they are not immutable (which is true). I am suprised to find that there doesn't seem to be a generic recursive 'make immutable' function. Does such a function exist? Is there a good reason why not? And how should I work around this problem?

Zero Piraeus
  • 56,143
  • 27
  • 150
  • 160
Chris Jefferson
  • 7,225
  • 11
  • 43
  • 66
  • 1
    The immutable equivalent of a list is a tuple. There is no generic function for the conversion, but it is easy enough to write. – jonrsharpe Oct 29 '14 at 14:40

1 Answers1

2

That's quite an unusual and unwieldy data structure to want to use as a dictionary key, and leads me to wonder whether this is an XY problem.

Leaving that observation to one side ... for the specific kind of structure you specify, containing nothing but lists (mutable) and strings and ints (immutable), a recursive function to convert all the lists to tuples is straightforward:

def tuplify(value):
    if isinstance(value, list):
        return tuple(tuplify(x) for x in value)
    else:
        return value

... and works as expected:

>>> tuplify(['data', [1, 'file', [], [1, 2]], 3])
('data', (1, 'file', (), (1, 2)), 3)

There's no solution for freezing arbitrary mutable objects, though. Some years ago, a freeze protocol for Python was proposed and rejected, but even if it had been accepted you'd have had to rely on every mutable object you were likely to come across implementing a __freeze__() method for it to work.

Community
  • 1
  • 1
Zero Piraeus
  • 56,143
  • 27
  • 150
  • 160
  • Thanks. My exact problem is that I have an existing function which takes a data structure as I describe (in practice it represents a tree), performs an expensive calculation (which can take 10 minutes), and returns a result. This function is functional -- it always returns the same output given a particular input. Therefore an obvious thing to do is to wrap it in a cache, to store previous calls and their return value. And the obvious (to me) way to store this cache is as a dict, hence the need for an immutable representation of my data structure. – Chris Jefferson Nov 03 '14 at 13:35