The effects of the three different methods to remove an element from a list:
remove removes the first matching value, not a specific index:
>>> a = [0, 2, 3, 2]
>>> a.remove(2)
>>> a
[0, 3, 2]
del removes the item at a specific index:
>>> a = [9, 8, 7, 6]
>>> del a[1]
>>> a
[9, 7, 6]
and pop removes the item at a specific index and returns it.
>>> a = [4, 3, 5]
>>> a.pop(1)
3
>>> a
[4, 5]
Their error modes are different too:
>>> a = [4, 5, 6]
>>> a.remove(7)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: list.remove(x): x not in list
>>> del a[7]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range
>>> a.pop(7)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: pop index out of range
Answer from Martijn Pieters on Stack OverflowThe effects of the three different methods to remove an element from a list:
remove removes the first matching value, not a specific index:
>>> a = [0, 2, 3, 2]
>>> a.remove(2)
>>> a
[0, 3, 2]
del removes the item at a specific index:
>>> a = [9, 8, 7, 6]
>>> del a[1]
>>> a
[9, 7, 6]
and pop removes the item at a specific index and returns it.
>>> a = [4, 3, 5]
>>> a.pop(1)
3
>>> a
[4, 5]
Their error modes are different too:
>>> a = [4, 5, 6]
>>> a.remove(7)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: list.remove(x): x not in list
>>> del a[7]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range
>>> a.pop(7)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: pop index out of range
Use del to remove an element by index, pop() to remove it by index if you need the returned value, and remove() to delete an element by value. The last requires searching the list, and raises ValueError if no such value occurs in the list.
When deleting index i from a list of n elements, the computational complexities of these methods are
del O(n - i)
pop O(n - i)
remove O(n)
Difference between del and .remove()? should one be preferred over the other? if so why?
Do You Ever del?
python - What is the difference between `__del__` and `__delete__`? - Stack Overflow
how is del(item) different from list.remove(item) in python list - Stack Overflow
Hi, I'm currently learning Python using, among others, automatetheboringstuff.com
It's a great resource, and I enjoy hacking through the projects.
I am now finishing Chapter 8 (https://automatetheboringstuff.com/chapter8/), and I'm doing the first project, "Create the Quiz File and Shuffle the Question Order".
In that project, at one point, we need to remove an item from a list. Said item's value is stored in a variable. I decided to use the .remove command, like this:
my_list = ['cat', 'dog', 'duck', 'rabbit'] item_to_be_removed = 'dog' my_list.remove(item_to_be_removed)
But the author uses instead the "del" command, such as:
del my_list[my_list.index(item_to_be_removed)]
My question: is there a difference ? It seems much easier to use the first method. I understand that "del" will delete an item using it's index number, and "remove" will remove the first instance of the value we want to delete. But in the context of the project, I don't see why del was chosen.
(Both "del" and ".remove" were explained in previous chapters of the book)
I've been coding in Python for years, mostly backend web-based stuff, but almost never del anything. Has anyone ever found interesting or compelling places to use it?
object.__del__(self):
Called when the instance is about to be destroyed. This is also called a finalizer or (improperly) a destructor. If a base class has a
__del__()method, the derived class’s__del__()method, if any, must explicitly call it to ensure proper deletion of the base class part of the instance.
This means that my_object.__del__ will get called by CPython's garbage collector after the reference count for my_object drops to zero.
object.__delete__(self, instance):
Called to delete the attribute on an instance
instanceof the owner class.
The __delete__ dunder method is related to python's notion of descriptors; a descriptor is "any object which defines the methods __get__(), __set__(), or __delete__()." Descriptors can be used to implement custom behavior for attribute lookup/assignment/deletion (via __get__/__set__/__delete__, respectively). If MyClass has a class variable x that has a __delete__ method then instance = MyClass(); del instance.x will cause x.__delete__ to be called:
class X:
def __delete__(self, instance):
print("custom delete method")
class MyClass:
x = X()
instance = MyClass()
del instance.x # prints "custom delete method"
del instance.x # prints "custom delete method" again
See the descriptor guide.
See also:
- The
delstatement: "Deletion of a name removes the binding of that name from the local or global namespace... Deletion of attribute references, subscriptions and slicings is passed to the primary object involved..." - The
delattrbuilt-in function. From the docs, "The function deletes the named attribute, provided the object allows it. For example,delattr(x, 'foobar')is equivalent todel x.foobar." object.__delattr__(self, name)is called when attribute deletion is attempted. According to the docs, "This should only be implemented ifdel obj.nameis meaningful for the object." Thus, defining a user class with the methodMyClass.__delattr__enables custom behavior when e.g. the statementdel my_object.an_attris invoked, or (equivalently) whendelattr(my_object, 'an_attr')is called.object.__delitem__(self, key)is "Called to implement deletion ofself[key]." Thus, defining a user class with the methodMyClass.__delitem__enables custom behavior when e.g. the statementdel my_object[a_key]is invoked.
__del__ is called when you delete an object and __delete__ is sometimes called when you delete an attribute of an object.
del x.my_num # __delete__
del x # __del__
ABOUT __del__:
The following code shows when __del__ gets called:
class MyClass:
def __init__(self):
file = open("really_cool_file.txt", "w+")
self._f = file
def __del__(self):
print("closing any open files ")
self._f.close()
my_instance = MyClass()
del my_instance
If my_instance is the last label pointing to the data, then del my_instance calls MyClass.__del__(my_instance)
Technically, del my_instance only deletes the label my_instance. Imagine people at a party all wearing names tags. Sometimes a person has 6 or 7 names tags on simultaneously, and other times, they only have one. Python will kick anyone out of the party who is not wearing at least one name tag. MyClass.__del__(my_instance) gets called when the last name-tag/label is removed from a piece of data.
The code above shows an example of when we make sure to close an open file. Another example might be to count of the number active instances of a given class:
class Klass:
count = 0
# `count` belongs to the class
# instances do not each get their own copy of `count`
def __init__(self):
type(self).count += 1
self.instance_var = "I belong to instances"
def __del__(self):
type(self).count -= 1
obj = Klass()
print(obj.count)
ABOUT __delete__
Unlike __del__, __delete__ has to do with descriptors.
The code below describes the behavior of obj.my_var or getattr(obj, “my_var”)
class Klaus: def getattribute(self, attrname): try: attribute = attrname from instance Klaus except AttributeError: attribute = attrname from class Klaus
# Begin code for handling "descriptors"
if hasattr(attribute, '__get__'):
attr = attribute.__get__(self, Klaus)
# End code for handling "descriptors"
return attribute
If my_var is a descriptor, then following two lines of code equivalent:
x = obj.my_var
x = Klass.my_var.__get__(obj, "my_var")
Just as __getattribute__ checks whether the attribute has a __get__ method or not, __delattr__ will check whether the attribute has a __delete__ method or not.
def __delattr__(self, name):
attribute = getattr(self, name)
if hasattr(attribute, "__delete__"):
attribute.__delete__(self)
else:
del self.__dict__[name]
You can see when __delete__ gets called by viewing the following code:
class desc:
def __delete__(descriptor, instance_of_Klaus):
print("attribute was deleted")
class Klaus:
d = desc()
def __init__(self):
pass
my_instance = Klaus()
del my_instance.d
When dealing with descriptors, the following lines of code are all equivalent:
del my_instance.d
delattr(my_instance, "d")
Klaus.d.__delete__(my_instance)
As a general rule, I would avoid modifying an object I'm iterating on. This could lead to very odd behaviors.
Have you considered a solutions with list comprehension? It seems to me like the most pythonic implementation in this case.
lst = ['XDA-OT', 'hi', 'loc', 'yeah']
lst = [itm for itm in lst if len(itm) <= 3]
You are having an index error because you are modifying the list as you go. The for loop receive a range(4) but in the end lst[4] does not exist anymore as you have deleted some items.
As for the question. del is a general function that delete an object whereas lst.remove() is a function of the list class. So in your case you can achieve what you want using both.
I would recommend that you go with the approach of @b3by as it makes usage of list comprehension which is faster in python than for loops as you where doing.