Reputation: 4959
I have a list of objects and they all have a data member visited
.
visited
is a boolean, default is False
.
I would like to be able to iterate over the list of objects to find an object that has not been visited.
If all the objects have been visited I want to detect that and set another boolean called done_searching
to False
.
Here is some pseudo code of what I'm trying to accomplish.
done_searching = False
while not done_searching:
objects = [object1, object2, object3]
foreach object in objects:
if object.visited == False:
non_visited_object = object
break
else if object.visited == True and last object in list
done_searching = True
break out of foreach
non_visited_object.do_something()
if (done_searching == True)
break out of main
I also had an idea that I could somehow use any()
... But it doesn't appear to work that way. Understandable loss of scope is the issue..
For example:
if any(object.visited == False for object in objects):
object.do_something()
else
searching_done = True
Upvotes: 0
Views: 48
Reputation: 35803
To get the first element of an array matching a criterion, use this:
next(obj for obj in objects if not obj.visited)
To have it return None
if nothing is found, as @DSM said, use the default parameter:
next((obj for obj in objects if not obj.visited), None)
If the default parameter is omitted, next
will raise a StopIteration
exception if no objects are found matching the criteria.
Upvotes: 3
Reputation: 28252
any
returns true if any of the entries in the array are true. The object
variable is scoped inside the any
call, so it's not visible outside of it. You can use a generator to accomplish this:
not_visited = (obj for obj in objects if not obj.visited).next()
if not_visited is None:
searching_done = True
This has the benefit of being concise and only performing exactly as many comparisons as necessary. It will also evaluate to None
if no object satisfies the condition.
Upvotes: 0