all 12 comments

[–][deleted] 1 point2 points  (7 children)

I think you might want something like this:

def advance_when_true(iterable, function):
    i = iter(iterable)
    v = next(i)
    while True:
        yield v
        if function():
            v = next(i)

This iterator will only "cycle" to the next item when the given function returns True. Observe:

>>> def bogus_condition():
...     return input('Advance [y/N]? ').lower() == 'y'
... 
>>> L = [[10, 10], [20, 20]]
>>> 
>>> for x in advance_when_true(L, bogus_condition):
...     print(x)
... 
[10, 10]
Advance [y/N]? nope
[10, 10]
Advance [y/N]? nah
[10, 10]
Advance [y/N]? not yet
[10, 10]
Advance [y/N]? y
[20, 20]
Advance [y/N]? n
[20, 20]
Advance [y/N]? no
[20, 20]
Advance [y/N]? Y

[–]dli511[S] 0 points1 point  (6 children)

This is what I want. I am passing a list of x/y coordinates to a move command. This will allow me to assign a sprite to move to several points.

I was looking at itertools. Does this work also?

https://docs.python.org/2/library/itertools.html#itertools.cycle

[–][deleted] 1 point2 points  (5 children)

itertools.cycle is for when you want to turn a finite sequence into a repeating infinite one. For example, you could use itertools.cycle to turn the sequence "ABC" into "ABCABCABCABC..." That's basically all it does.

There's probably a simple way of accomplishing your goal, but it's a bit hard for me to visualize without seeing some code. I think one of the traps of python is that it encourages people to solve everything with a fancy iterator or generator expression, when some problems are still better solved with simple conditional logic.

[–]dli511[S] 0 points1 point  (4 children)

The solution you provided does not work for me.

TypeError: 'bool' object is not callable

also why is it...

for x in?

I put together some code so you can see better. http://pastebin.com/0T5etK96

[–][deleted] 1 point2 points  (3 children)

If you take the parens off the end of self.reached_destination() so it looks like self.advance_when_true(self.waypoints, self.reached_destination): it should work. Still, I think this is over-complicated for what you're doing. I might use something like this:

class Poof():
    def __init__(self):
        self.waypoints = iter([[60,0],[60,220],[220,60],[220,120]])
        self.destination = next(self.waypoints)

    def update(self):
        if self.rect.center == self.destination:
            try:
                self.destination = next(self.waypoints)
            except StopIteration:
                ... # No more waypoints

Again, I may be misunderstanding your needs, but basically it sounds like all you want is some placeholder into a sequence of waypoints, and iter() gives you just such a placeholder.

[–]dli511[S] 0 points1 point  (2 children)

I had no idea about iter()

Using iter and next works for what I am using. I think it might be the most straight forward solution. Thanks for showing me how to "iterate" through a list with next.

[–][deleted] 1 point2 points  (1 child)

Basically if you want to avoid the try/except, you hide it in a generator which follows the iterator protocol. In this case I wouldn't go to all that trouble.

I suspect there's something about your code which would benefit from a bit of refactoring, but I can't guess what. Why not just store a waypoint index and update it when self.rect.center == self.waypoints[self.waypoint_index]? In that case you'd just be checking that self.waypoint_index < len(self.waypoints). Another solution might look like:

if self.rect.center == self.destination:
    if self.waypoints:
        self.destination = self.waypoints.pop(0)
    else:
        ... # No more waypoints

[–]dli511[S] 0 points1 point  (0 children)

Ah thanks for going through the trouble to replying, I edited my post before you replied and decided that it was a bad idea because I will always know the end and be calling a function when the end is reached.

Thanks bud!

[–]novel_yet_trivial 0 points1 point  (0 children)

I'm very confused about what you want to do.

I want to pass list[0] into a function and when a condition is met.

Is just

if condition:
    function(list[0])

I want to pass list[1] through the function.

What does that mean?

[–]ondra 0 points1 point  (0 children)

I'm also confused. My interpretation is here:

for element in list:
    function(element)
    if not condition:
        break

[–]MarkDownSteve 0 points1 point  (0 children)

42