DEAR PEOPLE FROM THE FUTURE: Here's what we've figured out so far...

Welcome! This is a Q&A website for computer programmers and users alike, focused on helping fellow programmers and users. Read more

What are you stuck on? Ask a question and hopefully somebody will be able to help you out!
+2 votes

I know about this:

l = [ "Alice", "Bob", "Charlie", "Bob", "Dave" ]
l.remove("Bob")

but it only removes the first one.

What I do:

while "Bob" in l:
    l.remove("Bob")

or this:

l = list(filter(lambda i: i != "Bob", l))

or this:

l = [ i for i in l if i != "Bob" ]

What I would like to do:

l.removeAll("Bob")
by
edited by
0

Is there any particular reason for not adopting solution 4), which is the most Pythonic?

0

Because it's not in-place and creates a second list so I have 2 lists in memory.

0

Would not the first list [ "Alice", "Bob", "Charlie", "Bob", "Dave" ] be dereferenced after you assign another list to l, and thus deleted (since Python uses a reference counter)?

0

Yes the first list will be deleted but my problem with list comprehension is that it creates the new list in memory before deleting the original (so I have 2 of them in memory at the same time, the original and the new one). The while loop example does not create a new list but I'd prefer a removeAll function (if it exists).

0

Then the loop is what you are looking for :)

0

Also, Python is not a performant language in general. These optimizations might make sense on embedded systems and the such, but there you probably would not use Python.

2 Answers

0 votes

[l.remove(i) for i in l if i == "Bob"]

But you have to discard the return value from this list comprehension. l will contain the filtered list.

You must use a list comprehension (square brackets) and not a generation expression (parentheses) because the latter is lazy.

by
+2 votes
l[:] = ( i for i in l if i != "Bob" )

Just as you can use the slice operator for getting a slice, x = y[2:5], you can use the slice assignment for setting a slice, x[0,2] = ["a", "b", "c"]. It will replace the slice with the content on the right. The slice [:] means "from zero to last position". It's in place because it utilizes a generator instead of list comprehension. Because it's modified in place, if you use other references those will change as well:

>>> x = [ "Alice", "Bob", "Charlie", "Bob", "Dave" ]
>>> y = x
>>> x[:] = ( i for i in x if i != "Bob" )
>>> x
['Alice', 'Charlie', 'Dave']
>>> y
['Alice', 'Charlie', 'Dave']

While this removes the loop, it's not a function (as you asked). If you want a function you will have to extend the base type or define a new function def removeAll(list, symbol).

by
edited by
Contributions licensed under CC0
...