Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different ways of deleting lists

I want to understand why:

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

behave so differently.

I ran a test for each to illustrate the differences I witnessed:

>>> # Test 1: Reset with a = []
... 
>>> a = [1,2,3]
>>> b = a
>>> a = []
>>> a
[]
>>> b
[1, 2, 3]
>>> 
>>> # Test 2: Reset with del a
... 
>>> a = [1,2,3]
>>> b = a
>>> del a
>>> a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> b
[1, 2, 3]
>>> 
>>> # Test 3: Reset with del a[:]
... 
>>> a = [1,2,3]
>>> b = a
>>> del a[:]
>>> a
[]
>>> b
[]

I did find Different ways of clearing lists, but I didn't find an explanation for the differences in behaviour. Can anyone clarify this?

like image 732
grasswistle Avatar asked Apr 22 '15 23:04

grasswistle


People also ask

What are the different ways to remove an element on a list?

There are three ways in which you can Remove elements from List: Using the remove() method. Using the list object's pop() method. Using the del operator.

Does list have remove method?

There are two remove() methods to remove elements from the List. E remove(int index): This method removes the element at the specified index and return it. The subsequent elements are shifted to the left by one place. This method throws IndexOutOfBoundsException is the specified index is out of range.


3 Answers

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  
like image 52
Malik Brahimi Avatar answered Sep 29 '22 12:09

Malik Brahimi


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.

like image 42
jonrsharpe Avatar answered Sep 29 '22 11:09

jonrsharpe


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.

like image 7
Padraic Cunningham Avatar answered Sep 29 '22 11:09

Padraic Cunningham