创建一个python列表,其中一个指针指向两个位置
我有一个python列表:创建一个python列表,其中一个指针指向两个位置,python,pointers,Python,Pointers,我有一个python列表: x = [1,1,1] 我将y设置为该列表,然后更改y,x更改,因为我有两个指向内存中同一位置的指针 y = x y[1] = 7 print x [1, 7, 1] 那很好。我是否可以列出x+y,这样当我改变x时,我也会改变y?这里有一些代码不起作用,但可能 澄清我的目标: q = x + y print q [1, 7, 1, 1, 7, 1] q[0] = 2 print q [2, 7, 1, 1, 7, 1] 但我希望q变成: [2, 7, 1, 2,
x = [1,1,1]
我将y设置为该列表,然后更改y,x更改,因为我有两个指向内存中同一位置的指针
y = x
y[1] = 7
print x
[1, 7, 1]
那很好。我是否可以列出x+y,这样当我改变x时,我也会改变y?这里有一些代码不起作用,但可能
澄清我的目标:
q = x + y
print q
[1, 7, 1, 1, 7, 1]
q[0] = 2
print q
[2, 7, 1, 1, 7, 1]
但我希望q变成:
[2, 7, 1, 2, 7, 1]
我希望这是明确的,我更希望这是可以实现的
编辑:为了回答为什么这会有用的问题,我打算将其用作环形缓冲区。假设我想将内容移动到位置p,并将其移动到位置p+1:而不是:
if p+1 == len(q):
q[0]= q[p]
else:
q[p+1] =q[p]
我可以这样做:
q[p+1] = q[p]
如果没有新的目标,你所要求的是不可能实现的 连接列表时,不会修改原始列表。您返回的是一个全新的列表,该列表没有附加到原始列表的引用 您可以通过创建自己的整数对象来实现该功能。目前,x[0]和y[0]在内存中指的是同一个位置。由于整数是不可变的,添加x和y会导致创建新的整数 我上面描述的实现示例如下:
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]
您可以创建某种自定义的
int
或list
对象来模拟此行为,但最简单的解决方案可能是将结构更改为列表列表
x = [1, 7, 1]
q = [x, x] # [[1, 7, 1], [1, 7, 1]]
x[0] = 2 # [[2, 7, 1], [2, 7, 1]]
q[0][2] = 3 # [[2, 7, 3], [2, 7, 3]]
但我并不认为这两种结构都有什么用处。即使是在删除和插入元素时,这也起到了作用:
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) )
用法:
>>> 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]
如果你正在寻找一个环绕访问列表,你有一些其他的可能性 通过
x[索引%len(x)]使用模运算符
如果需要,使用相同的模式设置和删除项目
您也可以将其封装在类中:
from collections import UserList
class WrapAroundList(UserList):
def __getitem__(self, index):
return super().__getitem__(index % len(self))
def __setitem__(self, index, value):
super().__setitem__(index % len(self), value)
像这样使用它:
>>> q=WrapAroundList([1,2,3])
>>> p=2
>>> q[p+1]=q[p]
>>> q
[3, 2, 3]
>>> q[-1]
3
>>> q[0]=5
>>> q[3]
5
>>> len(q)
3
不太可能。无论如何,不是标准列表。您可以创建一个具有模拟功能的类……描述这种行为有用的情况可能是有建设性的。由于我们已经知道您的确切尝试不起作用,了解最终目标可以让我们了解哪些需求可以协商(例如,q是否必须是一个列表?它是否必须是一个平面列表?它的元素是否需要是不可变的?它是否必须通过使用+运算符添加x和y来创建?)在不影响所需行为的情况下。如果您创建了子类列表
,则可以创建一个自定义的\uuuuuu setitem\uuuuuuu
方法来处理这个可能的重复项。非常感谢。实际上,我最后做了:chainedListProxy(x,x,x),我使用中间的第三个,它允许在两个方向上进行溢出环绕,而不考虑结束条件。我试图调整代码,使Q[0 ]索引中间第三中的第一个值,但不能完全排序。如果使用<代码> q= CHANEDistListAgent(x,x,x)< /> >索引> <代码> q[0 ] < /代码>,在这个例子中,索引x的第一个元素,这也是中间第三。也许更好的做法是描述您想要解决的问题,而不是实现什么(请参见)。我希望能够使用数组之外的值对x数组进行索引,并让它神奇地环绕。所以当我有一个长度为3的列表时,q[-2]将与q[1]或q[4]相同。事实证明,您的代码已经做到了这一点,所以我根本不必胡乱处理。这实际上对很多应用程序都很有用,所以我很惊讶,似乎有一种“为什么有人想这么做”的情绪在渗透。谢谢。这具有正确的功能,但我最终使用了下面Gunther Jena的答案。对于他的,我不必使用val和setval,这使它更符合人体工程学。
>>> q=WrapAroundList([1,2,3])
>>> p=2
>>> q[p+1]=q[p]
>>> q
[3, 2, 3]
>>> q[-1]
3
>>> q[0]=5
>>> q[3]
5
>>> len(q)
3