2

If iterating through a list of events, how can I stop at a certain condition and start iterating backwards through the list. e.g.

for p in pattern:
    for event in p:
        if event == 1:
        # Iterate backwards through p from current position until you reach the last event that equals 1

I think you could use something like reversed(p), but that would start at the end of p, and I'd like to start looking from the current position.

roncook
  • 287
  • 3
  • 13
  • Since you're iterating from the start of p, the first value ``1`` you find must also be the earliest one in the list. So iterating backwards to find an earlier one doesn't seem to make much sense as there can't be one. Is there more to your algorithm? – James Elderfield Jun 28 '17 at 16:51
  • There's quite a few 1's in this list, and it's not ordered. – roncook Jun 28 '17 at 16:54

3 Answers3

3

The Python for loop doesn't work how I think you expect it to. When you call for here, Python is literally assigning p[i] to a new copy of the variable event. It has no next object or previous object to reference.

If you want to know what your current position is, you'll need to use the enumerate() function.

for index, event in enumerate(p):
    print(index, event)

This would allow you to break your loop or create another subloop, and then re-transverse it from the specified point using reversed() or something similar.

Your code would look something like:

for p in pattern:
    for index, event in enumerate(p):
        if event == 1:
            for event2 in reversed(p[:index]):
                # do the things

I'm assuming you don't need to enumerate your reversal. If you do, changing the the innermost for statement to for in enumerate(reversed(p[:index]): should do the trick.

I've used a different event variable in case you wanted to reference the one that originally sent you down the reversal. That is not necessary if you don't need that feature.

Option 2:

An additional way (thanks @Scott) can be done using the p.index(event) value. It's less pythonic and will break your existing loop (maybe that matters maybe not), but it does work.

for p in pattern:
    for event in p:
        if event == 1:
            new_start = p.index(event)
for p in reversed(p[:new_start]):
Jacobm001
  • 4,431
  • 4
  • 30
  • 51
1

To reverse directions, you will need to remember the position index as you iterate. The enumerate() builtin function will help.

Once the reversal condition is found, use list slicing to isolate the portion you want to reiterate backwards. The reversed() builtin will take it from there.

>>> loe = ['e0', 'e1', 'e2', 'e3', 'e4', 'e5']
>>> for i, event in enumerate(loe):
        print event
        if event == 'e3':
            for event in reversed(loe[:i]):
                print event
            break


e0
e1
e2
e3
e2
e1
e0

Hope this helps :-)

Raymond Hettinger
  • 216,523
  • 63
  • 388
  • 485
0

Simply record the index and start traverse backward: should look something like this.

pattern = [[3,4,5],[7,8,9],[3,2,1,5,7,1],[8,1,8,8,1]]

for i in range(0, len(pattern)):
  for j in range(0, len(pattern[i])):
    print(pattern[i][j])
    if(pattern[i][j] == 1):
      print("found a event equals to 1")
      if(j == 0):
        print(" but its at the start of the list so there are no event equals to 1 before")
      else:
        reserveStartingIndex = j - 1 #to exclude itself 
        for r in range (reserveStartingIndex, 0, -1):
          if(pattern[i][r] == 1):
            print("found a event equals to 1 before at the index of: " + repr(r) )
          elif(r == 0):
            print("no event equals to 1 before")

you would get result like this:

3
4
5
7
8
9
3
2
1
found a event equals to 1
5
7
1
found a event equals to 1
found a event equals to 1 before at the index of: 2
8
1
found a event equals to 1
8
8
1
found a event equals to 1
found a event equals to 1 before at the index of: 1
OLIVER.KOO
  • 5,654
  • 3
  • 30
  • 62