通过引用添加列表

时间:2018-07-08 01:27:14

标签: python list reference

是否可以使用每个列表的引用而不是副本添加两个列表?

例如-

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 ++做到这一点的令人困惑的评论。

1 个答案:

答案 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 ++中一样,通常只需要从chainbegin(c)循环,而无需构建一个新的持久对象来保持它们。)

如果您因为我使用end(c)而认为是作弊的,我们可以自己定义:

itertools