Different ways of deleting lists

后端 未结 6 1059
攒了一身酷
攒了一身酷 2020-12-15 03:44

I want to understand why:

  • a = [];
  • del a; and
  • del a[:];

behave so differently.

I

相关标签:
6条回答
  • 2020-12-15 04:10

    To understand the difference between different ways of deleting lists, let us see each of them one by one with the help of images.

    >>> a1 = [1,2,3]
    

    A new list object is created and assigned to a1.

    i1

    >>> a2 = a1
    

    We assign a1 to a2. So, list a2 now points to the list object to which a1 points to.

    i2

    DIFFERENT METHODS EXPLAINED BELOW:

    Method-1 Using [] :

    >>> a1 = []
    

    i3

    On assigning an empty list to a1, there is no effect on a2. a2 still refers to the same list object but a1 now refers to an empty list.

    Method-2 Using del [:]

    >>> del a1[:]
    

    i4

    This deletes all the contents of the list object which a1 was pointing to. a1 now points to an empty list. Since a2 was also referring to the same list object, it also becomes an empty list.

    Method-3 Using del a1

    >>> del a1
    >>> a1
    NameError: name 'a1' is not defined
    

    i5

    This deletes the variable a1 from the scope. Here, just the variable a1 is removed, the original list is still present in the memory. a2 still points to that original list which a1 used to point to. If we now try to access a1, we will get a NameError.

    0 讨论(0)
  • 2020-12-15 04:11

    Of your three "ways of deleting Python lists", only one actually alters the original list object; the other two only affect the name.

    1. a = [] creates a new list object, and assigns it to the name a.
    2. del a deletes the name, not the object it refers to.
    3. del a[:] deletes all references from the list referenced by the name a (although, similarly, it doesn't directly affect the objects that were referenced from the list).

    It's probably worth reading this article on Python names and values to better understand what's going on here.

    0 讨论(0)
  • 2020-12-15 04:11

    Test 1: rebinds a to a new object, b still holds a reference to the original object, a is just a name by rebinding a to a new object does not change the original object that b points to.

    Test 2: you del the name a so it no longer exists but again you still have a reference to the object in memory with b.

    Test 3 a[:] just like when you copy a list or want to change all the elements of a list refers to references to the objects stored in the list not the name a. b gets cleared also as again it is a reference to a so changes to the content of a will effect b.

    The behaviour is documented:

    There is a way to remove an item from a list given its index instead of its value: the del statement. This differs from the pop() method which returns a value. The del statement can also be used to remove slices from a list or clear the entire list (which we did earlier by assignment of an empty list to the slice). For example:

    >>>
    >>> a = [-1, 1, 66.25, 333, 333, 1234.5]
    >>> del a[0]
    >>> a
    [1, 66.25, 333, 333, 1234.5]
    >>> del a[2:4]
    >>> a
    [1, 66.25, 1234.5]
    >>> del a[:]
    >>> a
    []
    

    del can also be used to delete entire variables:

    >>>
    >>> del a
    

    Referencing the name a hereafter is an error (at least until another value is assigned to it). We'll find other uses for del later.

    So only del a actually deletes a, a = [] rebinds a to a new object and del a[:] clears a. In your second test if b did not hold a reference to the object it would be garbage collected.

    0 讨论(0)
  • 2020-12-15 04:15
    del a
    

    is removing the variable a from the scope. Quoting from python docs:

    Deletion of a name removes the binding of that name from the local or global namespace, depending on whether the name occurs in a global statement in the same code block.

    del a[:]
    

    is simply removing the contents of a, since the deletion is passed to the a object, instead of applied to it. Again from the docs:

    Deletion of attribute references, subscriptions and slicings is passed to the primary object involved; deletion of a slicing is in general equivalent to assignment of an empty slice of the right type (but even this is determined by the sliced object).

    .

    0 讨论(0)
  • 2020-12-15 04:24

    Test 1

    >>> a = [1,2,3] # set a to point to a list [1, 2, 3]
    >>> b = a # set b to what a is currently pointing at
    >>> a = [] # now you set a to point to an empty list
    
    # Step 1: A --> [1 2 3]
    
    # Step 2: A --> [1 2 3] <-- B
    
    # Step 3: A --> [     ] [1 2 3] <-- B
    
    # at this point a points to a new empty list
    # whereas b points to the original list of a
    

    Test 2

    >>> a = [1,2,3] # set a to point to a list [1, 2, 3]
    >>> b = a # set b to what a is currently pointing at
    >>> del a # delete the reference from a to the list
    
    # Step 1: A --> [1 2 3]
    
    # Step 2: A --> [1 2 3] <-- B
    
    # Step 3:       [1 2 3] <-- B
    
    # so a no longer exists because the reference
    # was destroyed but b is not affected because
    # b still points to the original list
    

    Test 3

    >>> a = [1,2,3] # set a to point to a list [1, 2, 3]
    >>> b = a # set b to what a is currently pointing at
    >>> del a[:] # delete the contents of the original
    
    # Step 1: A --> [1 2 3]
    
    # Step 2: A --> [1 2 3] <-- B
    
    # Step 2: A --> [     ] <-- B
    
    # both a and b are empty because they were pointing 
    # to the same list whose elements were just removed  
    
    0 讨论(0)
  • 2020-12-15 04:27

    Of those three methods, only the third method actually results in deleting the list that 'a' points to. Lets do a quick overview.

    When you right a = [1, 2, 3] it creates a list in memory, with the items [1, 2, 3] and then gets 'a' to point to it. When you write b = a this preforms whats' called a 'shallow copy,' i.e. it makes 'b' point to the same block of memory as 'a.' a deep copy would involve copying the contents of the list into a new block of memory, then pointing to that.

    now, when you write a = [] you are creating a new list with no items in it, and getting 'a' to point to it. the original list still exists, and 'b' is pointing to it.

    in the second case, del a deletes the pointer to [1,2,3] and not the array it's self. this means b can still point to it.

    lastly, del a[:] goes through the data 'a' is pointing to and empties it's contents. 'a' still exists, so you can use it. 'b' also exists, but it points to the same empty list 'a' does, which is why it gives the same output.

    0 讨论(0)
提交回复
热议问题