NWS
NWS

Reputation: 33

While loop over a range?

I have a list of lists as shown below. I want to iterate the list and for each list item with 'yes' at index 1, I want to update index 4 with count of occurrences of 'no' before I get another yes and then add add 1 to it. My solution works except the 2nd to last item (435...) should have 2, but I'm getting 0.

Input data:

[[428, 'yes', 428, 0, 0],
 [429, 'yes', 429, 0, 0],
 [430, 'no', 430, 0, 0],
 [431, 'no', 431, 0, 0],
 [432, 'yes', 432, 0, 0],
 [433, 'yes', 433, 0, 0],
 [434, 'no', 434, 0, 0],
 [435, 'yes', 435, 0, 0],
 [436, 'no', 436, 0, 0]]

Desired Output:

[[428, 'yes', 428, 0, 1],
 [429, 'yes', 429, 0, 3],
 [430, 'no', 430, 0, 0],
 [431, 'no', 431, 0, 0],
 [432, 'yes', 432, 0, 1],
 [433, 'yes', 433, 0, 2],
 [434, 'no', 434, 0, 0],
 [435, 'yes', 435, 0, 2],
 [436, 'no', 436, 0, 0]]

Here is my entire script I'm using to test

fullchart = [
[428, 'yes', 428, 0, 0],
[429, 'yes', 429, 0, 0],
[430, 'no', 430, 0, 0],
[431, 'no', 431, 0, 0],
[432, 'yes', 432, 0, 0],
[433, 'yes', 433, 0, 0],
[434, 'no', 434, 0, 0],
[435, 'yes', 435, 0, 0],
[436, 'no', 436, 0, 0]
]

print('fullchart 1')
pprint.pprint(fullchart)

end_page = 0
for i in range(len(fullchart)):
    if fullchart[i][1] == 'yes':
        for b in range(i+1, len(fullchart)):
            print('printing b')
            print(b)
            if fullchart[b][1] == 'no':
                end_page += 1
            else:
                fullchart[i][4] = end_page + 1
                break
    else:
        pass

print('fullchart 2')
pprint.pprint(fullchart)

Upvotes: 1

Views: 65

Answers (2)

Mark
Mark

Reputation: 92440

It seems like the easiest way to deal with this is to iterate backwards over the list:

l = [
    [428, 'yes', 428, 0, 0],
    [429, 'yes', 429, 0, 0],
    [430, 'no', 430, 0, 0],
    [431, 'no', 431, 0, 0],
    [432, 'yes', 432, 0, 0],
    [433, 'yes', 433, 0, 0],
    [434, 'no', 434, 0, 0],
    [435, 'yes', 435, 0, 0],
    [436, 'no', 436, 0, 0]
]

count = 1

for row in reversed(l):
    if row[1] == 'no':
        count += 1
    else:
        row[4] = count
        count = 1
        

Making l:

[[428, 'yes', 428, 0, 1],
 [429, 'yes', 429, 0, 3],
 [430, 'no', 430, 0, 0],
 [431, 'no', 431, 0, 0],
 [432, 'yes', 432, 0, 1],
 [433, 'yes', 433, 0, 2],
 [434, 'no', 434, 0, 0],
 [435, 'yes', 435, 0, 2],
 [436, 'no', 436, 0, 0]]

That should be considerably more efficient too since it only looks at each item once.

Upvotes: 1

Prune
Prune

Reputation: 77837

The logic error is here:

        if fullchart[b][1] == 'no':
            end_page += 1
        else:
            fullchart[i][4] = end_page + 1
            break

Note that you update your yes-row entry only when you hit an answer that is not no. Since there is no such element after the final yes, that last desired update doesn't happen. You need to repeat that update after the end of the loop.

Also, I think you'll find this much easier to debug if you change the approach. Count consecutive no answers until you hit something else. At that point, back up to the previous yes row -- which you can find easily with that count -- and update its 4th element. Do it one last time after the loop.

Upvotes: 0

Related Questions