I have a python list:
x = [1,1,1]
I set y equal to that list and then change y, and x changes because I have two pointers to the same place in memory.
y = x
y[1] = 7
print x
[1, 7, 1]
That's all good. Is there anyway I can make a list of x+y so that when I change x, I also change y? Here's some code which doesn't work but maybe clarifies my goal:
q = x + y
print q
[1, 7, 1, 1, 7, 1]
q[0] = 2
print q
[2, 7, 1, 1, 7, 1]
but I'd LIKE q to instead become:
[2, 7, 1, 2, 7, 1]
I hope that's clear, and I hope even more that it's achievable!
EDIT: To respond to the inquiries as to why this would be useful, I intend to use it as a ring buffer. Say I want to take the contents at position p and move them to position p+1: Instead of:
if p+1 == len(q):
q[0]= q[p]
else:
q[p+1] =q[p]
I could just do:
q[p+1] = q[p]
This is doing the trick, even for deleting and inserting elements:
from collections import MutableSequence
from itertools import chain, islice
class ChainedListProxy(MutableSequence):
def __init__(self, *lists):
self._lists=lists
def _resolve_element(self, index):
""" returning list and subindex in that list """
for l in self._lists:
if index>=len(l):
index-=len(l)
else:
return l, index
raise IndexError('index out of range')
def __getitem__(self, index):
l, i=self._resolve_element(index)
return l[i]
def __delitem__(self, index):
l, i=self._resolve_element(index)
del l[i]
def __setitem__(self, index, value):
if isinstance(index, slice):
indicies=index.indices(len(self))
l, i=self._resolve_element(index)
l[i]=value
def insert(self, index, value):
l, i=self._resolve_element(index)
l.insert(i, value)
def __len__(self):
return sum( (len(l) for l in self._lists) )
Usage:
>>> x=[1,2,3]
>>> q=ChainedListProxy(x,x)
>>> q[0]
1
>>> q[3]=5
>>> q[0]
5
>>> list(q)
[5, 2, 3, 5, 2, 3]
What you are asking for is not achievable without making a new object.
When you concatenate lists, you are not modifying the original lists. You are returning a completely new list that has no references attached to the original list.
You can somewhat implement that functionality by creating your own integer object. Currently x[0] and y[0] refer to the same place in memory. Since integers are immutable, adding x and y causes you to create new integers.
An example of the implementation I described above is here:
class myInt:
def __init__(self, val):
self.val = val
def setval(self, new):
self.val = new
def __repr__(self):
return str(self.val)
x = [myInt(0), myInt(1), myInt(2)]
y = x
z = x + y
print(z)
>>>[0, 1, 2, 0, 1, 2]
z[0].setval(10)
>>>[10, 1, 2, 10, 1, 2]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With