2

I'm familiar with list.remove, which will mutate a list by deleting the first instance of the passed element, raising a value error if the element is not present.

What I'm looking for is a function that does not mutate the list, but rather returns a copy of the list without the given element. So, for instance, instead of executing

l = [1,2,3]
l.remove(2)

I would execute

l = [1,2,3].remove(2)

The purpose of this is to make it a bit simpler to put this type of logic into a dict definition. So that rather than:

l = [1,2,3]
l.remove(2)
d = {
  'theList': l
}

I just have

d = {
  'theList': [1,2,3].remove(2)
}

Does such a function exist?

Note that I want to remove only the first instance of the value in question, not all instances, so [x for x in [1,2,3] if x != 2] does not do what I want. Though I'm not sure if there is a list comprehension way to do this.

ewok
  • 20,148
  • 51
  • 149
  • 254
  • Are the answers really any improvement on the complexity of your code? – roganjosh Aug 10 '18 at 18:07
  • @roganjosh well, it could prevent an unnecessary local variable, for instance, which my linter is complaining about. – ewok Aug 10 '18 at 18:10
  • I have a feeling they're slower than your current approach, double indexing a list and then concatenating the results, for example. Or copying the whole list. I'm not sure I would trust the linter here, but I'd want it timed. And, IMO, there's no readability to be gained. – roganjosh Aug 10 '18 at 18:13

3 Answers3

4

Such a method does not exist for the list type.

Although, you can write it yourself by copying the list first, removing the element and returning the new list.

Code

def remove(lst, el):
    new_lst = lst.copy()
    new_lst.remove(el)
    return new_lst

Example

>>> l=[1,2,3]
>>> remove(l, 2)
[1, 3]
>>> l
[1, 2, 3]
Olivier Melançon
  • 21,584
  • 4
  • 41
  • 73
3

You can use index:

a = [1,2,3]
{'a': a[:a.index(2)] + a[a.index(2)+1:]}

or as function:

def remove(a, e):
    idx = a.index(e)
    return a[:idx] + a[idx+1:]
Daniel
  • 42,087
  • 4
  • 55
  • 81
-2

Could you do:

lst = [1, 2, 3]

def remove(l, i):
    r = l[:]
    r.remove(i)
    return r

>>> remove(lst, 2)
[1, 3]
>>> lst 
[1, 2, 3]
N Chauhan
  • 3,407
  • 2
  • 7
  • 21