1

This is a sample code of what I want to do...

class A():
number = 0
List = []
for i in range(5):
    state = A()
    state.number = i
    List.append(state)
print List
Numbers = [1,2,3]

Now I want to delete class objects in List whose number is in Numbers. What is the fastest way to do it ? Also if someone can suggest a more pythonic way of doing this than by simply creating two for loops one for that of Numbers and other of List and then removing from the List.

1
  • 1
    Numbers is a list of ints. You are assigning an individual int to the .number of each element in List. A list of numbers is never going to be the same as an individual number. Did you mean "...whose number is in Numbers"? Commented Dec 17, 2010 at 14:15

3 Answers 3

8

First of, instead of having a class variable like A.number as in:

class A():
    number = 0

you should generally write a __init__ method that sets the number only on the instance.

class A(object):
    def __init__(self, number):
        self.number = number

Now the rest of your code can be written simply as:

List = [A(i) for i in range(5)]
print List

To efficiently find items (without two loops) you need sets:

Numbers = set([1,2,3]) 

x in Numbers now takes constant time. Otherwise Python would have to loop through the List to find a number.

The result you want looks like:

filtered = [a for a in List if a.number in Numbers]
Sign up to request clarification or add additional context in comments.

5 Comments

@user506710 Yes if you do not use the self prefix.
@user506710: Yes, anything you write on the class level is shared between all instances. For example, all the methods are shared, which is exactly what you'd expect from a class. But when you want to store something on a instance of a class, you need to write a method. In this case, the initialisation method __init__ takes the instance that is passed into this method as self and stores the number on it.
@THC4k: number is not shared between all instances: codepad.org/r9itOCcK. (instance).number will just set the number property. From the docs: By definition, all attributes of a class that are function objects define corresponding methods of its instances. If an attribute is not a function it will not be defined on the instance.
@THC4k For this output I was always using class A() because it still worked.... Please explain if each instance has different number how are you saying that number would be shared with all instances of A
@user506710: Sorry, i messed that up, read Felix' comment for the details. Basically, the code you had has the same effect, for different reasons: First number is a shared class variable on A. But when you do A().number=i, a new variable (by the same name) is added to the instance. So there is nothing shared in the end. I still think you should write a __init__ method though, if only to avoid having to think about this after all.
3

Using List Comprehension,

NewList=[x for x in List if x.number not in Numbers]

1 Comment

That is what I was about to suggest. Very pythonic imo, reminds me of some LINQ expressions I've seen
2

How about filter?

List = filter(lambda x: x.number not in Numbers, List)

Note that filter(function, iterable) is equivalent to [item for item in iterable if function(item)]

It would be even better if you define Numbers as a set.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.