# How to set mutable an inmutable sequence.

I think the title is quite descriptive.

I would like to know, how can you set mutable an inmutable sequence. Is that even possible?

I would be very grateful if you can link me the file of the sage documentation where I can find that info.

Thanks.

edit retag close merge delete

Sort by » oldest newest most voted

Well, you can do the following, but I'm not sure if this is what you want:

sage: seq = (1,2,3,4)
sage: seq[0]=2
---------------------------------------------------------------------------
TypeError: 'tuple' object does not support item assignment
sage: seq2 = list(seq)
sage: seq2[0]=2
sage: seq2
[2, 2, 3, 4]


However, my guess is that you want to make seq above a mutable object. I don't think this is possible - you can try to search the Python site to see if you can find an exception to this. In general, if you want to make something mutable, the type has to start as mutable, as far as I know, and Python is strongly typed (i.e. you can't change the type of an object once it's created).

more

And no, I'm not interested in an argument with someone in the peanut gallery about 'duck' or 'strong' typing or anything else about what Python's typing should be called...

( 2011-01-03 04:05:37 -0600 )edit

That's not a sequence.

seq = (1,2,3,4) <-- tuple sage: seq2 = list(seq) <-- list

I mean how to do mutable an inmutable sequence(http://www.sagemath.org/doc/reference...) like, for example: v = Sequence(range(5), universe=ZZ)

more

Thanks for the clarification (see DSM's reply). By the way, you should be able to edit your original question without the need to create an 'answer' yourself - hopefully even with not much 'karma'!

( 2011-01-03 14:10:38 -0600 )edit

(1) Ah. Here capitalization matters, so that "a sequence" refers to sequences in general, and both lists and tuples are sequences. "Sequence" refers to the object you're asking about named "Sequence". kcrisman answered the general case, which is what I thought you were asking too.

(2) If I understand you (and I'm not sure that I do), then his answer still applies: you make a new object which is mutable. In Python mutability isn't usually considered a switch you can toggle but a feature of types; for practical reasons Sage makes it easier to freeze objects, but often to "undo" this you need to make a new object.

sage: v = Sequence(range(5), universe=ZZ)
sage: v
[0, 1, 2, 3, 4]
sage: v.is_mutable()
True
sage: v[2] = 3
sage: v
[0, 1, 3, 3, 4]
sage:
sage: # make it immutable
sage: v.set_immutable()
sage: v.is_mutable()
False
sage: v[3] = 8
---------------------------------------------------------------------------
[.. deletia]
sage: # make mutable again
sage: v = Sequence(v) # or seq(v), that works too
sage: v
[0, 1, 3, 3, 4]
sage: v.is_mutable()
True
sage: v[3] = 8
sage: v
[0, 1, 3, 8, 4]


That's what the ValueError message is telling you to do: work with a new copy.

more

Okey, thank you for the answer. Sorry about the Sequence staff, I guess that's because of my english vocabulary

( 2011-01-03 19:19:36 -0600 )edit

I think i have found the solution:

v._set_ inmutable=FALSE

more

Too long for a comment. Playing games with the mutability isn't a solution, it's a problem waiting to happen!

Tik, if you're going to do this, it would be "v._is_immutable = False", with "is" instead of "set", two ms, and different capitalization on False: remember that Python is case-sensitive. (Think "impossible" to get the spelling right, and don't blame me for the inconsistency. :^) I'd also be quite surprised if this were documented: single-underscore variables are usually considered private, and you often don't even document changes in them beween versions.

But bypassing the interface and changing the internal state directly is a bad idea -- if someone provides a setter they probably did it for a reason -- and a way to cause hard-to-detect bugs, because then you can make all sorts of mistakes that the immutability was trying to prevent you from making.


sage: u = Sequence([0,1,2,3,5])
sage: v = Sequence([0,1,2,3,4])
sage: hash(u)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
[...]
ValueError: immutable sequences are unhashable
sage: # [Hey, there's a typo: this should be "mutable sequences are unhashable".
sage: # Anyone with commit privs, please fix.]
sage: u.set_immutable()
sage: v.set_immutable()
sage: hash(u)
-3958796579501393844
sage:
sage: d = {u: 3, v: 4}  # since they're immutable we can hash them, and use them as dictionary keys
sage: d
{[0, 1, 2, 3, 5]: 3, [0, 1, 2, 3, 4]: 4}
sage:
sage: u[4] = 4
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
[...]
sage: u._is_immutable = False # don't do this!
sage: u[4] = 4
sage: d
{[0, 1, 2, 3, 4]: 3, [0, 1, 2, 3, 4]: 4}
sage: # what?!


With Python people usually don't go out of their way to prevent you from making mistakes the way they do in (e.g.) C++, and so all sorts of things are possible. But with this power comes responsibility, namely the responsibility not to shoot yourself in the foot when there's no need to.

more

Thanks for the explanation. There is nothing about "_is_immutable" on the doc?

( 2011-01-06 03:47:11 -0600 )edit

Probably this is an internal Python thing?

( 2011-01-06 15:30:20 -0600 )edit

@Tik: you can search as well as I can! I didn't find anything, but I didn't look that hard. @kcrisman: _is_immutable isn't a Python flag, it's on the Sage side.

( 2011-01-06 15:57:36 -0600 )edit

I've been trying but it's really hard to find something about that on the doc :S

( 2011-01-06 21:21:30 -0600 )edit

Look in the source of structure.mutability.pyx and structure.mutability_py.py. And of course structure.sequence.py.

( 2011-01-07 17:08:16 -0600 )edit