Reputation: 100
I have tried searching online for this, but unfortunately have not been able to come up with a solution so far, so I was hoping someone might be able to help me. My basic question is how can I check whether an object is already in a list?
I am currently working on a Rubik's Cube solver, and have created a class called MyCube
, where each object has 4 properties:
def __init__(self, cp=None, co=None, ep=None, eo=None):
There are a number of methods for changing the properties, and I have also created methods for __eq__
and __ne__
as follows:
def __eq__(self, other):
if type(other) is type(self):
return self.__dict__ == other.__dict__
return False
def __ne__(self, other):
return not self.__eq__(other)
I have a list of cubes MyMoveCube = [MyCube() for i in range(18)]
and each cube goes through various different transformations. I then have another cube MyNewCube
and I want to check whether it is already in MyMoveCube
and if not to add it to the list.
I have tried the following, but I find that this gets very slow very quickly as the size of MyMoveCube
increases:
for current_move in MyMoveCube:
if current_move == MyNewCube:
break
MyMoveCube.append(MyNewCube)
My question is, is there a better way to do this without looping through it each time?
Upvotes: 2
Views: 1983
Reputation: 281949
If you want to do something if MyNewCube
is already in MyMoveCube
,
if MyNewCube in MyMoveCube:
do_whatever()
or if you want to do something if it isn't,
if MyNewCube not in MyMoveCube:
do_whatever()
(I initially didn't see the part about running into speed problems; this answer just demonstrates in
syntax. Testing lists for containment is horribly slow; for efficiency, see the other answer.)
Upvotes: 2
Reputation: 59681
"but I find that this gets very slow very quickly as the size of MyMoveCube increases"
You will want to look into using a set to store your MyCube
instances.
MyMoveCube = set([MyCube() for i in range(18)])
Hashing an object and checking whether it's in a set
is a very efficient operation - O(1)
in the average case compared to O(n)
in the average case for a list.
You can still use the same in
operators with a set, with much faster lookup:
if MyNewCube in MyMoveCube:
# in cube
EDIT:
If you need to keep track of the order of the items in the set, you could possibly use a set
AND a list
. The list for tracking the order and the set for testing membership.
Upvotes: 1