Elements, Array and Lists With Clone Protocol¶
This module defines several classes which are subclasses of
Element and which roughly implement
the “prototype” design pattern (see [Prototype_pattern], [GHJV1994]). Those classes are
intended to be used to model mathematical objects, which are by essence
immutable. However, in many occasions, one wants to construct the
data-structure encoding of a new mathematical object by small modifications of
the data structure encoding some already built object. For the resulting
data-structure to correctly encode the mathematical object, some structural
invariants must hold. One problem is that, in many cases, during the
modification process, there is no possibility but to break the invariants.
For example, in a list modeling a permutation of \(\{1,\dots,n\}\), the integers must be distinct. A very common operation is to take a permutation to make a copy with some small modifications, like exchanging two consecutive values in the list or cycling some values. Though the result is clearly a permutations there’s no way to avoid breaking the permutations invariants at some point during the modifications.
The main purpose of this module is to define the class
- ClonableElementas an abstract super class,
and its subclasses:
- ClonableArrayfor arrays (lists of fixed length) of objects;
- ClonableListfor (resizable) lists of objects;
- NormalizedClonableListfor lists of objects with a normalization method;
- ClonableIntArrayfor arrays of int.
See also
The following parents from sage.structure.list_clone_demo
demonstrate how to use them:
- IncreasingArrays()(see- IncreasingArrayand the parent class- IncreasingArrays)
- IncreasingLists()(see- IncreasingListand the parent class- IncreasingLists)
- SortedLists()(see- SortedListand the parent class- SortedLists)
- IncreasingIntArrays()(see- IncreasingIntArrayand the parent class- IncreasingIntArrays)
EXAMPLES:
We now demonstrate how
IncreasingArray works, creating an
instance el through its parent IncreasingArrays():
sage: from sage.structure.list_clone_demo import IncreasingArrays
sage: P = IncreasingArrays()
sage: P([1, 4 ,8])
[1, 4, 8]
>>> from sage.all import *
>>> from sage.structure.list_clone_demo import IncreasingArrays
>>> P = IncreasingArrays()
>>> P([Integer(1), Integer(4) ,Integer(8)])
[1, 4, 8]
If one tries to create this way a list which in not increasing, an error is raised:
sage: IncreasingArrays()([5, 4 ,8])
Traceback (most recent call last):
...
ValueError: array is not increasing
>>> from sage.all import *
>>> IncreasingArrays()([Integer(5), Integer(4) ,Integer(8)])
Traceback (most recent call last):
...
ValueError: array is not increasing
Once created modifying el is forbidden:
sage: el = P([1, 4 ,8])
sage: el[1] = 3
Traceback (most recent call last):
...
ValueError: object is immutable; please change a copy instead.
>>> from sage.all import *
>>> el = P([Integer(1), Integer(4) ,Integer(8)])
>>> el[Integer(1)] = Integer(3)
Traceback (most recent call last):
...
ValueError: object is immutable; please change a copy instead.
However, you can modify a temporarily mutable clone:
sage: with el.clone() as elc:
....:      elc[1] = 3
sage: [el, elc]
[[1, 4, 8], [1, 3, 8]]
>>> from sage.all import *
>>> with el.clone() as elc:
...      elc[Integer(1)] = Integer(3)
>>> [el, elc]
[[1, 4, 8], [1, 3, 8]]
We check that the original and the modified copy now are in a proper immutable state:
sage: el.is_immutable(), elc.is_immutable()
(True, True)
sage: elc[1] = 5
Traceback (most recent call last):
...
ValueError: object is immutable; please change a copy instead.
>>> from sage.all import *
>>> el.is_immutable(), elc.is_immutable()
(True, True)
>>> elc[Integer(1)] = Integer(5)
Traceback (most recent call last):
...
ValueError: object is immutable; please change a copy instead.
You can break the property that the list is increasing during the modification:
sage: with el.clone() as elc2:
....:     elc2[1] = 12
....:     print(elc2)
....:     elc2[2] = 25
[1, 12, 8]
sage: elc2
[1, 12, 25]
>>> from sage.all import *
>>> with el.clone() as elc2:
...     elc2[Integer(1)] = Integer(12)
...     print(elc2)
...     elc2[Integer(2)] = Integer(25)
[1, 12, 8]
>>> elc2
[1, 12, 25]
But this property must be restored at the end of the with block; otherwise
an error is raised:
sage: with elc2.clone() as el3:
....:     el3[1] = 100
Traceback (most recent call last):
...
ValueError: array is not increasing
>>> from sage.all import *
>>> with elc2.clone() as el3:
...     el3[Integer(1)] = Integer(100)
Traceback (most recent call last):
...
ValueError: array is not increasing
Finally, as an alternative to the with syntax one can use:
sage: el4 = copy(elc2)
sage: el4[1] = 10
sage: el4.set_immutable()
sage: el4.check()
>>> from sage.all import *
>>> el4 = copy(elc2)
>>> el4[Integer(1)] = Integer(10)
>>> el4.set_immutable()
>>> el4.check()
REFERENCES:
AUTHORS:
- Florent Hivert (2010-03): initial revision 
- class sage.structure.list_clone.ClonableArray[source]¶
- Bases: - ClonableElement- Array with clone protocol. - The class of objects which are - Elementbehave as arrays (i.e. lists of fixed length) and implement the clone protocol. See- ClonableElementfor details about clone protocol.- INPUT: - parent– a- Parent
- lst– list
- check– boolean specifying if the invariant must be checked using method- check()
- immutable– boolean (default:- True); whether the created element is immutable
 - See also - IncreasingArrayfor an example of usage.- EXAMPLES: - sage: from sage.structure.list_clone_demo import IncreasingArrays sage: IA = IncreasingArrays() sage: ia1 = IA([1, 4, 6]); ia1 [1, 4, 6] sage: with ia1.clone() as ia2: ....: ia2[1] = 5 sage: ia2 [1, 5, 6] sage: with ia1.clone() as ia2: ....: ia2[1] = 7 Traceback (most recent call last): ... ValueError: array is not increasing - >>> from sage.all import * >>> from sage.structure.list_clone_demo import IncreasingArrays >>> IA = IncreasingArrays() >>> ia1 = IA([Integer(1), Integer(4), Integer(6)]); ia1 [1, 4, 6] >>> with ia1.clone() as ia2: ... ia2[Integer(1)] = Integer(5) >>> ia2 [1, 5, 6] >>> with ia1.clone() as ia2: ... ia2[Integer(1)] = Integer(7) Traceback (most recent call last): ... ValueError: array is not increasing - check()[source]¶
- Check that - selffulfill the invariants.- This is an abstract method. Subclasses are supposed to overload - check.- EXAMPLES: - sage: from sage.structure.list_clone import ClonableArray sage: ClonableArray(Parent(), [1,2,3]) # indirect doctest Traceback (most recent call last): ... NotImplementedError: this should never be called, please overload the check method sage: from sage.structure.list_clone_demo import IncreasingArrays sage: el = IncreasingArrays()([1,2,4]) # indirect doctest - >>> from sage.all import * >>> from sage.structure.list_clone import ClonableArray >>> ClonableArray(Parent(), [Integer(1),Integer(2),Integer(3)]) # indirect doctest Traceback (most recent call last): ... NotImplementedError: this should never be called, please overload the check method >>> from sage.structure.list_clone_demo import IncreasingArrays >>> el = IncreasingArrays()([Integer(1),Integer(2),Integer(4)]) # indirect doctest 
 - count(key)[source]¶
- Return number of - i’s for which- s[i] == key- EXAMPLES: - sage: from sage.structure.list_clone_demo import IncreasingArrays sage: c = IncreasingArrays()([1,2,2,4]) sage: c.count(1) 1 sage: c.count(2) 2 sage: c.count(3) 0 - >>> from sage.all import * >>> from sage.structure.list_clone_demo import IncreasingArrays >>> c = IncreasingArrays()([Integer(1),Integer(2),Integer(2),Integer(4)]) >>> c.count(Integer(1)) 1 >>> c.count(Integer(2)) 2 >>> c.count(Integer(3)) 0 
 - index(x, start=None, stop=None)[source]¶
- Return the smallest - ksuch that- s[k] == xand- i <= k < j- EXAMPLES: - sage: from sage.structure.list_clone_demo import IncreasingArrays sage: c = IncreasingArrays()([1,2,4]) sage: c.index(1) 0 sage: c.index(4) 2 sage: c.index(5) Traceback (most recent call last): ... ValueError: 5 is not in list - >>> from sage.all import * >>> from sage.structure.list_clone_demo import IncreasingArrays >>> c = IncreasingArrays()([Integer(1),Integer(2),Integer(4)]) >>> c.index(Integer(1)) 0 >>> c.index(Integer(4)) 2 >>> c.index(Integer(5)) Traceback (most recent call last): ... ValueError: 5 is not in list 
 
- class sage.structure.list_clone.ClonableElement[source]¶
- Bases: - Element- Abstract class for elements with clone protocol. - This class is a subclass of - Elementand implements the “prototype” design pattern (see [Prototype_pattern], [GHJV1994]). The role of this class is:- to manage copy and mutability and hashing of elements 
- to ensure that at the end of a piece of code an object is restored in a meaningful mathematical state. 
 - A class - Cinheriting from- ClonableElementmust implement the following two methods- obj.__copy__()– returns a fresh copy of obj
- obj.check()– returns nothing, raise an exception if- objdoesn’t satisfy the data structure invariants
 - and ensure to call - obj._require_mutable()at the beginning of any modifying method.- Additionally, one can also implement - obj._hash_()– return the hash value of- obj
 - Then, given an instance - objof- C, the following sequences of instructions ensures that the invariants of- new_objare properly restored at the end:- with obj.clone() as new_obj: ... # lot of invariant breaking modifications on new_obj ... # invariants are ensured to be fulfilled - The following equivalent sequence of instructions can be used if speed is needed, in particular in Cython code: - new_obj = obj.__copy__() ... # lot of invariant breaking modifications on new_obj ... new_obj.set_immutable() new_obj.check() # invariants are ensured to be fulfilled - Finally, if the class implements the - _hash_method, then- ClonableElementensures that the hash value can only be computed on an immutable object. It furthermore caches it so that it is only computed once.- Warning - for the hash caching mechanism to work correctly, the hash value cannot be 0. - EXAMPLES: - The following code shows a minimal example of usage of - ClonableElement. We implement a class or pairs \((x,y)\) such that \(x < y\):- sage: from sage.structure.list_clone import ClonableElement sage: class IntPair(ClonableElement): ....: def __init__(self, parent, x, y): ....: ClonableElement.__init__(self, parent=parent) ....: self._x = x ....: self._y = y ....: self.set_immutable() ....: self.check() ....: def _repr_(self): ....: return "(x=%s, y=%s)"%(self._x, self._y) ....: def check(self): ....: if self._x >= self._y: ....: raise ValueError("Incorrectly ordered pair") ....: def get_x(self): return self._x ....: def get_y(self): return self._y ....: def set_x(self, v): self._require_mutable(); self._x = v ....: def set_y(self, v): self._require_mutable(); self._y = v - >>> from sage.all import * >>> from sage.structure.list_clone import ClonableElement >>> class IntPair(ClonableElement): ... def __init__(self, parent, x, y): ... ClonableElement.__init__(self, parent=parent) ... self._x = x ... self._y = y ... self.set_immutable() ... self.check() ... def _repr_(self): ... return "(x=%s, y=%s)"%(self._x, self._y) ... def check(self): ... if self._x >= self._y: ... raise ValueError("Incorrectly ordered pair") ... def get_x(self): return self._x ... def get_y(self): return self._y ... def set_x(self, v): self._require_mutable(); self._x = v ... def set_y(self, v): self._require_mutable(); self._y = v - Note - we don’t need to define - __copy__since it is properly inherited from- Element.- We now demonstrate the behavior. Let’s create an - IntPair:- sage: myParent = Parent() sage: el = IntPair(myParent, 1, 3); el (x=1, y=3) sage: el.get_x() 1 - >>> from sage.all import * >>> myParent = Parent() >>> el = IntPair(myParent, Integer(1), Integer(3)); el (x=1, y=3) >>> el.get_x() 1 - Modifying it is forbidden: - sage: el.set_x(4) Traceback (most recent call last): ... ValueError: object is immutable; please change a copy instead. - >>> from sage.all import * >>> el.set_x(Integer(4)) Traceback (most recent call last): ... ValueError: object is immutable; please change a copy instead. - However, you can modify a mutable copy: - sage: with el.clone() as el1: ....: el1.set_x(2) sage: [el, el1] [(x=1, y=3), (x=2, y=3)] - >>> from sage.all import * >>> with el.clone() as el1: ... el1.set_x(Integer(2)) >>> [el, el1] [(x=1, y=3), (x=2, y=3)] - We check that the original and the modified copy are in a proper immutable state: - sage: el.is_immutable(), el1.is_immutable() (True, True) sage: el1.set_x(4) Traceback (most recent call last): ... ValueError: object is immutable; please change a copy instead. - >>> from sage.all import * >>> el.is_immutable(), el1.is_immutable() (True, True) >>> el1.set_x(Integer(4)) Traceback (most recent call last): ... ValueError: object is immutable; please change a copy instead. - A modification which doesn’t restore the invariant \(x < y\) at the end is illegal and raise an exception: - sage: with el.clone() as elc2: ....: elc2.set_x(5) Traceback (most recent call last): ... ValueError: Incorrectly ordered pair - >>> from sage.all import * >>> with el.clone() as elc2: ... elc2.set_x(Integer(5)) Traceback (most recent call last): ... ValueError: Incorrectly ordered pair - clone(check=True)[source]¶
- Return a clone that is mutable copy of - self.- INPUT: - check– boolean indicating if- self.check()must be called after modifications
 - EXAMPLES: - sage: from sage.structure.list_clone_demo import IncreasingArrays sage: el = IncreasingArrays()([1,2,3]) sage: with el.clone() as el1: ....: el1[2] = 5 sage: el1 [1, 2, 5] - >>> from sage.all import * >>> from sage.structure.list_clone_demo import IncreasingArrays >>> el = IncreasingArrays()([Integer(1),Integer(2),Integer(3)]) >>> with el.clone() as el1: ... el1[Integer(2)] = Integer(5) >>> el1 [1, 2, 5] 
 - is_immutable()[source]¶
- Return - Trueif- selfis immutable (cannot be changed) and- Falseif it is not.- To make - selfimmutable use- self.set_immutable().- EXAMPLES: - sage: from sage.structure.list_clone_demo import IncreasingArrays sage: el = IncreasingArrays()([1,2,3]) sage: el.is_immutable() True sage: copy(el).is_immutable() False sage: with el.clone() as el1: ....: print([el.is_immutable(), el1.is_immutable()]) [True, False] - >>> from sage.all import * >>> from sage.structure.list_clone_demo import IncreasingArrays >>> el = IncreasingArrays()([Integer(1),Integer(2),Integer(3)]) >>> el.is_immutable() True >>> copy(el).is_immutable() False >>> with el.clone() as el1: ... print([el.is_immutable(), el1.is_immutable()]) [True, False] 
 - is_mutable()[source]¶
- Return - Trueif- selfis mutable (can be changed) and- Falseif it is not.- To make this object immutable use - self.set_immutable().- EXAMPLES: - sage: from sage.structure.list_clone_demo import IncreasingArrays sage: el = IncreasingArrays()([1,2,3]) sage: el.is_mutable() False sage: copy(el).is_mutable() True sage: with el.clone() as el1: ....: print([el.is_mutable(), el1.is_mutable()]) [False, True] - >>> from sage.all import * >>> from sage.structure.list_clone_demo import IncreasingArrays >>> el = IncreasingArrays()([Integer(1),Integer(2),Integer(3)]) >>> el.is_mutable() False >>> copy(el).is_mutable() True >>> with el.clone() as el1: ... print([el.is_mutable(), el1.is_mutable()]) [False, True] 
 - set_immutable()[source]¶
- Makes - selfimmutable, so it can never again be changed.- EXAMPLES: - sage: from sage.structure.list_clone_demo import IncreasingArrays sage: el = IncreasingArrays()([1,2,3]) sage: el1 = copy(el); el1.is_mutable() True sage: el1.set_immutable(); el1.is_mutable() False sage: el1[2] = 4 Traceback (most recent call last): ... ValueError: object is immutable; please change a copy instead. - >>> from sage.all import * >>> from sage.structure.list_clone_demo import IncreasingArrays >>> el = IncreasingArrays()([Integer(1),Integer(2),Integer(3)]) >>> el1 = copy(el); el1.is_mutable() True >>> el1.set_immutable(); el1.is_mutable() False >>> el1[Integer(2)] = Integer(4) Traceback (most recent call last): ... ValueError: object is immutable; please change a copy instead. 
 
- class sage.structure.list_clone.ClonableIntArray[source]¶
- Bases: - ClonableElement- Array of integers with clone protocol. - The class of objects which are - Elementbehave as list of int and implement the clone protocol. See- ClonableElementfor details about clone protocol.- INPUT: - parent– a- Parent
- lst– list
- check– boolean specifying if the invariant must be checked using method- check()
- immutable– boolean (default:- True); whether the created element is immutable
 - See also - IncreasingIntArrayfor an example of usage.- check()[source]¶
- Check that - selffulfill the invariants.- This is an abstract method. Subclasses are supposed to overload - check.- EXAMPLES: - sage: from sage.structure.list_clone import ClonableArray sage: ClonableArray(Parent(), [1,2,3]) # indirect doctest Traceback (most recent call last): ... NotImplementedError: this should never be called, please overload the check method sage: from sage.structure.list_clone_demo import IncreasingIntArrays sage: el = IncreasingIntArrays()([1,2,4]) # indirect doctest - >>> from sage.all import * >>> from sage.structure.list_clone import ClonableArray >>> ClonableArray(Parent(), [Integer(1),Integer(2),Integer(3)]) # indirect doctest Traceback (most recent call last): ... NotImplementedError: this should never be called, please overload the check method >>> from sage.structure.list_clone_demo import IncreasingIntArrays >>> el = IncreasingIntArrays()([Integer(1),Integer(2),Integer(4)]) # indirect doctest 
 - index(item)[source]¶
- EXAMPLES: - sage: from sage.structure.list_clone_demo import IncreasingIntArrays sage: c = IncreasingIntArrays()([1,2,4]) sage: c.index(1) 0 sage: c.index(4) 2 sage: c.index(5) Traceback (most recent call last): ... ValueError: list.index(x): x not in list - >>> from sage.all import * >>> from sage.structure.list_clone_demo import IncreasingIntArrays >>> c = IncreasingIntArrays()([Integer(1),Integer(2),Integer(4)]) >>> c.index(Integer(1)) 0 >>> c.index(Integer(4)) 2 >>> c.index(Integer(5)) Traceback (most recent call last): ... ValueError: list.index(x): x not in list 
 - list()[source]¶
- Convert - selfinto a Python list.- EXAMPLES: - sage: from sage.structure.list_clone_demo import IncreasingIntArrays sage: I = IncreasingIntArrays()(range(5)) sage: I == list(range(5)) False sage: I.list() == list(range(5)) True sage: I = IncreasingIntArrays()(range(1000)) sage: I.list() == list(range(1000)) True - >>> from sage.all import * >>> from sage.structure.list_clone_demo import IncreasingIntArrays >>> I = IncreasingIntArrays()(range(Integer(5))) >>> I == list(range(Integer(5))) False >>> I.list() == list(range(Integer(5))) True >>> I = IncreasingIntArrays()(range(Integer(1000))) >>> I.list() == list(range(Integer(1000))) True 
 
- class sage.structure.list_clone.ClonableList[source]¶
- Bases: - ClonableArray- List with clone protocol. - The class of objects which are - Elementbehave as lists and implement the clone protocol. See- ClonableElementfor details about clone protocol.- See also - IncreasingListfor an example of usage.- append(el)[source]¶
- Appends - elto- self.- INPUT: - el– any object
 - EXAMPLES: - sage: from sage.structure.list_clone_demo import IncreasingLists sage: el = IncreasingLists()([1]) sage: el.append(3) Traceback (most recent call last): ... ValueError: object is immutable; please change a copy instead. sage: with el.clone() as elc: ....: elc.append(4) ....: elc.append(6) sage: elc [1, 4, 6] sage: with el.clone() as elc: ....: elc.append(4) ....: elc.append(2) Traceback (most recent call last): ... ValueError: array is not increasing - >>> from sage.all import * >>> from sage.structure.list_clone_demo import IncreasingLists >>> el = IncreasingLists()([Integer(1)]) >>> el.append(Integer(3)) Traceback (most recent call last): ... ValueError: object is immutable; please change a copy instead. >>> with el.clone() as elc: ... elc.append(Integer(4)) ... elc.append(Integer(6)) >>> elc [1, 4, 6] >>> with el.clone() as elc: ... elc.append(Integer(4)) ... elc.append(Integer(2)) Traceback (most recent call last): ... ValueError: array is not increasing 
 - extend(it)[source]¶
- Extend - selfby the content of the iterable- it.- INPUT: - it– any iterable
 - EXAMPLES: - sage: from sage.structure.list_clone_demo import IncreasingLists sage: el = IncreasingLists()([1, 4, 5, 8, 9]) sage: el.extend((10,11)) Traceback (most recent call last): ... ValueError: object is immutable; please change a copy instead. sage: with el.clone() as elc: ....: elc.extend((10,11)) sage: elc [1, 4, 5, 8, 9, 10, 11] sage: el2 = IncreasingLists()([15, 16]) sage: with el.clone() as elc: ....: elc.extend(el2) sage: elc [1, 4, 5, 8, 9, 15, 16] sage: with el.clone() as elc: ....: elc.extend((6,7)) Traceback (most recent call last): ... ValueError: array is not increasing - >>> from sage.all import * >>> from sage.structure.list_clone_demo import IncreasingLists >>> el = IncreasingLists()([Integer(1), Integer(4), Integer(5), Integer(8), Integer(9)]) >>> el.extend((Integer(10),Integer(11))) Traceback (most recent call last): ... ValueError: object is immutable; please change a copy instead. >>> with el.clone() as elc: ... elc.extend((Integer(10),Integer(11))) >>> elc [1, 4, 5, 8, 9, 10, 11] >>> el2 = IncreasingLists()([Integer(15), Integer(16)]) >>> with el.clone() as elc: ... elc.extend(el2) >>> elc [1, 4, 5, 8, 9, 15, 16] >>> with el.clone() as elc: ... elc.extend((Integer(6),Integer(7))) Traceback (most recent call last): ... ValueError: array is not increasing 
 - insert(index, el)[source]¶
- Inserts - elin- selfat position- index.- INPUT: - el– any object
- index– any int
 - EXAMPLES: - sage: from sage.structure.list_clone_demo import IncreasingLists sage: el = IncreasingLists()([1, 4, 5, 8, 9]) sage: el.insert(3, 6) Traceback (most recent call last): ... ValueError: object is immutable; please change a copy instead. sage: with el.clone() as elc: ....: elc.insert(3, 6) sage: elc [1, 4, 5, 6, 8, 9] sage: with el.clone() as elc: ....: elc.insert(2, 6) Traceback (most recent call last): ... ValueError: array is not increasing - >>> from sage.all import * >>> from sage.structure.list_clone_demo import IncreasingLists >>> el = IncreasingLists()([Integer(1), Integer(4), Integer(5), Integer(8), Integer(9)]) >>> el.insert(Integer(3), Integer(6)) Traceback (most recent call last): ... ValueError: object is immutable; please change a copy instead. >>> with el.clone() as elc: ... elc.insert(Integer(3), Integer(6)) >>> elc [1, 4, 5, 6, 8, 9] >>> with el.clone() as elc: ... elc.insert(Integer(2), Integer(6)) Traceback (most recent call last): ... ValueError: array is not increasing 
 - pop(index=-1)[source]¶
- Remove - self[index]from- selfand returns it.- INPUT: - index– integer (default: -1)
 - EXAMPLES: - sage: from sage.structure.list_clone_demo import IncreasingLists sage: el = IncreasingLists()([1, 4, 5, 8, 9]) sage: el.pop() Traceback (most recent call last): ... ValueError: object is immutable; please change a copy instead. sage: with el.clone() as elc: ....: print(elc.pop()) 9 sage: elc [1, 4, 5, 8] sage: with el.clone() as elc: ....: print(elc.pop(2)) 5 sage: elc [1, 4, 8, 9] - >>> from sage.all import * >>> from sage.structure.list_clone_demo import IncreasingLists >>> el = IncreasingLists()([Integer(1), Integer(4), Integer(5), Integer(8), Integer(9)]) >>> el.pop() Traceback (most recent call last): ... ValueError: object is immutable; please change a copy instead. >>> with el.clone() as elc: ... print(elc.pop()) 9 >>> elc [1, 4, 5, 8] >>> with el.clone() as elc: ... print(elc.pop(Integer(2))) 5 >>> elc [1, 4, 8, 9] 
 - remove(el)[source]¶
- Remove the first occurrence of - elfrom- self.- INPUT: - el– any object
 - EXAMPLES: - sage: from sage.structure.list_clone_demo import IncreasingLists sage: el = IncreasingLists()([1, 4, 5, 8, 9]) sage: el.remove(4) Traceback (most recent call last): ... ValueError: object is immutable; please change a copy instead. sage: with el.clone() as elc: ....: elc.remove(4) sage: elc [1, 5, 8, 9] sage: with el.clone() as elc: ....: elc.remove(10) Traceback (most recent call last): ... ValueError: list.remove(x): x not in list - >>> from sage.all import * >>> from sage.structure.list_clone_demo import IncreasingLists >>> el = IncreasingLists()([Integer(1), Integer(4), Integer(5), Integer(8), Integer(9)]) >>> el.remove(Integer(4)) Traceback (most recent call last): ... ValueError: object is immutable; please change a copy instead. >>> with el.clone() as elc: ... elc.remove(Integer(4)) >>> elc [1, 5, 8, 9] >>> with el.clone() as elc: ... elc.remove(Integer(10)) Traceback (most recent call last): ... ValueError: list.remove(x): x not in list 
 
- class sage.structure.list_clone.NormalizedClonableList[source]¶
- Bases: - ClonableList- List with clone protocol and normal form. - This is a subclass of - ClonableListwhich call a method- normalize()at creation and after any modification of its instance.- See also - SortedListfor an example of usage.- EXAMPLES: - We construct a sorted list through its parent: - sage: from sage.structure.list_clone_demo import SortedLists sage: SL = SortedLists() sage: sl1 = SL([4,2,6,1]); sl1 [1, 2, 4, 6] - >>> from sage.all import * >>> from sage.structure.list_clone_demo import SortedLists >>> SL = SortedLists() >>> sl1 = SL([Integer(4),Integer(2),Integer(6),Integer(1)]); sl1 [1, 2, 4, 6] - Normalization is also performed atfer modification: - sage: with sl1.clone() as sl2: ....: sl2[1] = 12 sage: sl2 [1, 4, 6, 12] - >>> from sage.all import * >>> with sl1.clone() as sl2: ... sl2[Integer(1)] = Integer(12) >>> sl2 [1, 4, 6, 12] - normalize()[source]¶
- Normalize - self.- This is an abstract method. Subclasses are supposed to overload - normalize(). The call- self.normalize()is supposed to- call - self._require_mutable()to check that- selfis in a proper mutable state
- modify - selfto put it in a normal form
 - EXAMPLES: - sage: from sage.structure.list_clone_demo import SortedList, SortedLists sage: l = SortedList(SortedLists(), [2,3,2], False, False) sage: l [2, 2, 3] sage: l.check() Traceback (most recent call last): ... ValueError: list is not strictly increasing - >>> from sage.all import * >>> from sage.structure.list_clone_demo import SortedList, SortedLists >>> l = SortedList(SortedLists(), [Integer(2),Integer(3),Integer(2)], False, False) >>> l [2, 2, 3] >>> l.check() Traceback (most recent call last): ... ValueError: list is not strictly increasing