代码之家  ›  专栏  ›  技术社区  ›  Charles Anderson

Python列表切片语法没有明显的原因

  •  35
  • Charles Anderson  · 技术社区  · 16 年前

    我偶尔会看到Python代码中使用的列表片段语法如下:

    newList = oldList[:]
    

    newList = oldList
    

    还是我遗漏了什么?

    5 回复  |  直到 15 年前
        1
  •  52
  •   ConcernedOfTunbridgeWells    15 年前

    [:] Shallow copies

    A. Deep Copy 也会复制所有名单成员。

    # ================================================================
    # === ShallowCopy.py =============================================
    # ================================================================
    #
    class Foo:
        def __init__(self, data):
            self._data = data
    
    aa = Foo ('aaa')
    bb = Foo ('bbb')
    
    # The initial list has two elements containing 'aaa' and 'bbb'
    OldList = [aa,bb]
    print OldList[0]._data
    
    # The shallow copy makes a new list pointing to the old elements
    NewList = OldList[:]
    print NewList[0]._data
    
    # Updating one of the elements through the new list sees the
    # change reflected when you access that element through the
    # old list.
    NewList[0]._data = 'xxx'
    print OldList[0]._data
    
    # Updating the new list to point to something new is not reflected
    # in the old list.
    NewList[0] = Foo ('ccc')
    print NewList[0]._data
    print OldList[0]._data
    

    在pythonshell中运行它会得到以下脚本。我们可以看到 其状态通过旧列表通过引用更新,并且可以 通过旧列表访问对象时看到。最后,更改 新列表现在引用的是另一个对象。

    >>> # ================================================================
    ... # === ShallowCopy.py =============================================
    ... # ================================================================
    ... #
    ... class Foo:
    ...     def __init__(self, data):
    ...         self._data = data
    ...
    >>> aa = Foo ('aaa')
    >>> bb = Foo ('bbb')
    >>>
    >>> # The initial list has two elements containing 'aaa' and 'bbb'
    ... OldList = [aa,bb]
    >>> print OldList[0]._data
    aaa
    >>>
    >>> # The shallow copy makes a new list pointing to the old elements
    ... NewList = OldList[:]
    >>> print NewList[0]._data
    aaa
    >>>
    >>> # Updating one of the elements through the new list sees the
    ... # change reflected when you access that element through the
    ... # old list.
    ... NewList[0]._data = 'xxx'
    >>> print OldList[0]._data
    xxx
    >>>
    >>> # Updating the new list to point to something new is not reflected
    ... # in the old list.
    ... NewList[0] = Foo ('ccc')
    >>> print NewList[0]._data
    ccc
    >>> print OldList[0]._data
    xxx
    
        2
  •  49
  •   Joachim Sauer    15 年前

    正如NXC所说,Python变量名实际上指向一个对象,而不是内存中的特定位置。

    newList = oldList oldList 也会改变 newList .

    newList = oldList[:] ,它“切片”列表,并创建一个新列表。的默认值 [:] 是0,并且是列表的结尾,因此它复制所有内容。因此,它创建了一个新列表,其中包含第一个列表中包含的所有数据,但两个列表都可以在不更改另一个列表的情况下进行更改。

        3
  •  12
  •   user21037 user21037    16 年前

    正如已经回答的那样,我将简单地添加一个简单的演示:

    >>> a = [1, 2, 3, 4]
    >>> b = a
    >>> c = a[:]
    >>> b[2] = 10
    >>> c[3] = 20
    >>> a
    [1, 2, 10, 4]
    >>> b
    [1, 2, 10, 4]
    >>> c
    [1, 2, 3, 20]
    
        4
  •  4
  •   kaleissin    16 年前

    千万不要认为Python中的“a=b”意味着“将b复制到a”。如果两边都有变量,你就不可能真正知道这一点。相反,可以将其视为“给b额外的名称a”。

    如果b是一个不可变的对象(如数字、元组或字符串),那么是的,其效果是得到一个副本。但那是因为当你处理不可变的(可能应该被称为 , 蠕虫 )你

    如果b是可变的,那么 总是要做一些额外的事情,以确保你有一个真正的副本 . . 对于列表,它就像一个切片一样简单:a=b[:]。

    可变性也是导致以下情况的原因:

    def myfunction(mylist=[]): 
        pass
    

    ... 并不像你想象的那样。

    http://docs.python.org/library/copy.html

        5
  •  -2
  •   abhiomkar    15 年前

    浅拷贝: (将内存块从一个位置复制到另一个位置)

    a = ['one','two','three']
    
    b = a[:]
    
    b[1] = 2
    
    print id(a), a #Output: 1077248300 ['one', 'two', 'three']
    print id(b), b #Output: 1077248908 ['one', 2, 'three']
    

    深度复制: (复制对象引用)

    a = ['one','two','three']
    
    b = a
    
    b[1] = 2
    
    
    print id(a), a #Output: 1077248300 ['one', 2, 'three']
    print id(b), b #Output: 1077248300 ['one', 2, 'three']