1

Am trying to learn some basic list comprehension in python and here's the code I was messing around with:

class myClass:
    def __init__(self,num):
        self.num = num

x = myClass(1)
y = myClass(2)
z = myClass(3)

obj = [x,y,z]

Here, I want to delete an object from the list "obj" whose self.num value is 3, how do I do that? Also assume every object in the list has it's own unique self.num value.

mathfux
  • 5,759
  • 1
  • 14
  • 34

4 Answers4

3

You can implement __eq__ for your class. With this approach you hide the internal details of your class and it will be easier to change the equality logic in the future without breaking code.

see https://docs.python.org/3/reference/datamodel.html#object.__eq__

class myClass:
    def __init__(self,num):
        self.num = num
    def __eq__(self,other):
        if isinstance(other, self.__class__):
            return self.num == other.num
        else:
            return False
    def __repr__(self):
        return f'num: {self.num}'

x = myClass(1)
y = myClass(2)
z = myClass(3)

to_delete = myClass(3)

objs = [x,y,z]
filtered_objs = [obj for obj in objs if obj != to_delete]
print(filtered_objs)

output

[num: 1, num: 2]
balderman
  • 22,927
  • 7
  • 34
  • 52
1

Quite fast way to do it is to use Python builtin method filter:

list(filter(lambda x:x.num!=3, obj))

This is a little faster than list comprehension.

mathfux
  • 5,759
  • 1
  • 14
  • 34
  • 1
    Good answer overall (functional programming-wise), but actually, [list comprehension tends to be faster than filter](https://stackoverflow.com/questions/3013449/list-comprehension-vs-lambda-filter). It varies, but for this particular case timeit has it at 2x faster on my PC. – DarrylG Sep 12 '20 at 18:34
  • Alright guys, this is a new thing about iterators I did know before and I was wrong. I timed it for a list with 10M instances and comprehension is 50% faster in case remaining list is small and 30% faster in case there are very little removable items. – mathfux Sep 12 '20 at 19:13
0

This can be implemented in various ways, but general algorithm will be:

  1. Find this object
  2. Remove from the list

To find the object you need to do a loop of some kind, for example:

for o in obj:
    if o.num == 3:
        index = obj.index(o)

Now you have the index of the object, you can remove it with obj.pop(index).

Another way to do it is a list comprehension:

obj = [o for o in obj if o.num != 3]
Konrad Talik
  • 912
  • 8
  • 22
  • 1
    What is that list comprehension meant to do? – alani Sep 12 '20 at 18:14
  • 1
    It is still not to be recommended - https://stackoverflow.com/questions/5753597/is-it-pythonic-to-use-list-comprehensions-for-just-side-effects – alani Sep 12 '20 at 18:21
0

You can do it simply by list comprehension

obj = [i for i in obj if i.num != 3]
Sarthak Kumar
  • 304
  • 5
  • 16