Search code examples
pythonlistobject

Deleting elements from list or recreating new list (python)


What it the best/fastest way to delete objects from list? Deleting some objects:

[objects.remove(o) for o in objects if o.x <= 0]

or recreating new object:

new_objects = [o for o in objects if o.x > 0]

Solution

  • For starters, don't use list comprehensions for side effects. It needlessly creates a list of None's here, which is simply ignored and garbage collected, and is just bad style. List comprehensions are for functional mapping/filtering operations to create new lists.

    However, even converted to an equivalent loop there is a classic bug:

    >>> objects = [1,1,2,2,1,1]
    >>> for obj in objects:
    ...     if obj == 2:
    ...         objects.remove(obj)
    ...
    >>> objects
    [1, 1, 2, 1, 1]
    

    This is because the internal iterator essentially keeps and index which it simply increments. Since the list changes size by removing an item, every index is shifted down, and an item is skipped. So when there are two matching items to be removed in a row, one is skipped.

    But more to the point, removing from a list in a loop is inefficient even if you do it correctly.

    It is quadratic time, whereas creating the new list is linear. So really, I think those are the clear advantages of creating a new list.

    As pointed out by @Selcuk in the comments, the advantage of modifying the list is that you don't use auxiliary space.