Anh Pham
Anh Pham

Reputation: 695

Remove last matching value from a list in Python

Let's say I have a list [1, 2, 3, 4, 2, 5]. Since 2 occurs twice, I want to remove the last occurrence of two. This is what I have done so far.

list.reverse()
list.remove(value) # value = 2
list.reverse()

But it seems that if I'm doing reversing twice for deleting a value, the algorithm complexity would be O(n). Is there any faster way of doing it?

Upvotes: 3

Views: 2571

Answers (5)

Ebram Shehata
Ebram Shehata

Reputation: 621

This is a simpler function to remove an element's last occurrence in a list if found:

def right_remove(l: list, element: Any) -> None:
    try:
        index = l[::-1].index(element)
    except ValueError:
        return
    
    l.pop(len(l) - index - 1)

Upvotes: 0

Laurent LAPORTE
Laurent LAPORTE

Reputation: 23002

IMO, the most efficient would be by iterating the list in reverse order, find the value 2, delete it and break the loop:

l = [1, 2, 3, 4, 2, 5]

for index, item in enumerate(reversed(l)):
    if item == 2:
        l.pop(len(l) - 1 - index)
        break

You get:

[1, 2, 3, 4, 5]

That way you don’t copy the list in memory nor loop twice.

Upvotes: 1

Aaditya Ura
Aaditya Ura

Reputation: 12689

You can create a dict , since dict can have unique values :

values=[1, 2, 3, 4, 2, 5]


no_repeat ={}
for i,j in enumerate(values):
    if j not in no_repeat:
        no_repeat[i]=j
    else:
        pass

print(no_repeat.values())

output

[1, 2, 3, 4, 5]

Upvotes: 1

cdlane
cdlane

Reputation: 41925

This approach removes one of the reversals at least:

def rremove(alist, x):
    alist.pop(len(alist) - alist[::-1].index(x) - 1)

my_list = [1, 2, 3, 4, 2, 5]

print(my_list)

rremove(my_list, 2)

print(my_list)

OUTPUT

[1, 2, 3, 4, 2, 5]
[1, 2, 3, 4, 5]

Just like list.remove(), it raises ValueError if the value is not present.

Upvotes: 1

Yogi
Yogi

Reputation: 633

if value in list:
    list.reverse()
    list.remove('ch')
    list.reverse()

The most pythonic way would be to do a try: except around remove:

list.reverse()
try:
    list.remove(value)
except:
    pass
list.reverse()

As per your comment on speed, both of these methods are O(N), as x in list and list.reverse() are both O(N), so there's not much between them. If you expect the element to usually be there, you can save the x in list check by using try: catch, however if you expect it to usually not be there, you can save the 2 reverse()s by checking for membership first.

Upvotes: 1

Related Questions