How to append a modified list into a list?
Peter Otten
__peter__ at web.de
Sat Nov 19 04:40:06 EST 2016
jfong at ms4.hinet.net wrote:
> I have a working list 'tbl' and recording list 'm'. I want to append 'tbl'
> into 'm' each time when the 'tbl' was modified. I will record the change
> by append it through the function 'apl'.
>
> For example:
>
>>>>tbl=[0,0]
>>>>m=[]
>
>>>>tbl[0]=1
>>>>apl(tbl)
>>>>m
> [[1,0]]
>
>>>>tbl[1]=2
>>>>apl(tbl)
>>>>m
> [[1,0], [1,2]]
>
> How to define this function properly?
>
> Obviously the most intuitive way doesn't work.
> def apl0(tbl):
> m.append(tbl)
>
> and introducing a local variable will not help either.
> def apl1(tbl):
> w=tbl
> m.append(w)
>
> I figure out a workable way, but looks ugly.
> def apl2(tbl):
> w=[]
> w[:]=tbl
> m.append(w)
>
> I know those binding tricks between names and objects. Just wondering if
> there is an elegant way of doing this:-)
>
> --Jach
And now for something completely different ;)
What if you only record the changes to the list? For a long list that would
save space at the expense of calculation time. For example:
$ cat list_history.py
import collections
from itertools import islice
class List(collections.Sequence):
def __init__(self, items):
self._items = list(items)
self._history = []
def __setitem__(self, index, value):
if isinstance(index, slice):
value = list(value)
old = self._items[index]
if len(old) != len(value):
raise ValueError("size changes not supported")
else:
old = self._items[index]
self._history.append((index, old))
self._items[index] = value
def __getitem__(self, index):
return self._items[index]
def __len__(self):
return len(self._items)
def __repr__(self):
return repr(self._items)
def historic_state(self, n):
items = self._items[:]
for index, value in islice(reversed(self._history), n):
items[index] = value
return items
def history_len(self):
return len(self._history) + 1
if __name__ == "__main__":
items = List("abcdefghijk")
print(items)
# apply some changes
items[3] = "foo"
items[7] = "bar"
items[3] = 42
items[3:6] = "xyz"
items[5:7] = (1, 2)
print(items)
# let's go back in time
for i in range(items.history_len()):
print("#{}: {}".format(i, items.historic_state(i)))
$ python3 list_history.py
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']
['a', 'b', 'c', 'x', 'y', 1, 2, 'bar', 'i', 'j', 'k']
#0: ['a', 'b', 'c', 'x', 'y', 1, 2, 'bar', 'i', 'j', 'k']
#1: ['a', 'b', 'c', 'x', 'y', 'z', 'g', 'bar', 'i', 'j', 'k']
#2: ['a', 'b', 'c', 42, 'e', 'f', 'g', 'bar', 'i', 'j', 'k']
#3: ['a', 'b', 'c', 'foo', 'e', 'f', 'g', 'bar', 'i', 'j', 'k']
#4: ['a', 'b', 'c', 'foo', 'e', 'f', 'g', 'h', 'i', 'j', 'k']
#5: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']
More information about the Python-list
mailing list