是否可以使用每个列表的引用而不是副本添加两个列表?
例如-
first_list = [1,2,3]
second_list = [5,6]
new_list = first_list + second_list
print(new_list) # Will print [1,2,3,5,6]
first_list.append(4)
print(new_list) # Should print [1,2,3,4,5,6]
有没有办法在Python中做到这一点?还是代码重写是我唯一的选择?
编辑:我删除了有关使用C ++做到这一点的令人困惑的评论。
答案 0 :(得分:4)
在Python中,您不能像在C ++中那样直接执行此操作。
但是您可以使用与C ++完全相同的方式在Python中间接地做到这一点:通过编写一个同时保留在列表和调度上的对象。
例如:
class TwoLists(collections.abc.Sequence):
def __init__(self, a, b):
self.a, self.b = a, b
def __len__(self):
return len(self.a) + len(self.b)
def __getitem__(self, idx):
# cheating a bit, not handling slices or negative indexing
if idx < len(self.a):
return self.a[idx]
else:
return self.b[idx - len(self.a)]
现在:
>>> first_list = [1,2,3]
>>> second_list = [5,6]
>>> two_lists = TwoLists(first_list, second_list)
>>> print(*two_lists)
1 2 3 5 6
>>> first_list.append(4)
>>> print(*two_lists)
1 2 3 4 5 6
我想您在这里缺少的是Python和C ++在变量如何工作方面的根本区别。简而言之,用C ++术语来说,每个Python变量(以及属性和列表位置等)都是一个引用变量。
误导性减少:
C ++变量(和属性等)是内存位置-它们是值所在的位置。如果希望a
是对b
中值的引用,则必须对b进行引用,并将其存储在a
中。 (C ++有点魔力,可以让您定义诸如int& a = b
之类的引用变量,但是您以后不能再将a
重新分配为引用c
;如果如果需要的话,必须显式使用C风格的指针。)
Python变量(等)是值的名称,而值则位于它们想要的任何位置。如果要让a
引用a
中的值,只需将a
绑定到与b
绑定的相同值上即可。 (而且,与C ++不同,您可以随时重新分配a = b
。)
当然,代价是性能:在Python中有一个额外的间接方法可以从其名称中获取任何值,而在C ++中,仅当使用指针变量时才会发生这种情况。但是,与Python的其他开销(解释字节码和在字典中动态查找名称等)相比,这笔费用几乎总是看不见的,因此对于高级语言来说,不给您选择就有意义。>
话虽这么说,通常没有充分的理由以 两种语言来执行此操作。 Python和C ++标准库都是围绕(类似但不同的迭代概念)设计的。
在Python中,通常通常不需要一个序列,而只是一个可迭代的序列。将两个可迭代对象链接在一起很简单:
a = c
是的,我只能在>>> from itertools import chain
>>> first_list = [1,2,3]
>>> second_list = [5,6]
>>> print(*chain(first_list, second_list))
1 2 3 5 6
>>> first_list.append(4)
>>> print(*chain(first_list, second_list))
1 2 3 4 5 6
上进行一次迭代,但是通常这就是您所需要的。 (就像在C ++中一样,通常只需要从chain
到begin(c)
循环,而无需构建一个新的持久对象来保持它们。)
如果您因为我使用end(c)
而认为是作弊的,我们可以自己定义:
itertools