Loop confusion

26 Sep, 2013

Justin B writes:

I recently started the section on "For Loops" and am somewhat confused about something. The section (page 55) runs a loop for "HugeHairyPants." I setup the loop as you indicated and actually understood the result just fine.

However, I decided to add a variable in the mix and went one step further. Here is my script:

hugehairypants = ['huge', 'hairy', 'pants']
for i in hugehairypants:
    print(i)
    for j in hugehairypants:
        print(j)
        for k in hugehairypants:
            print(k)

This loop doesn't seem to follow the same progression of the other loop or maybe I just don't understand it correctly. I figured it would print a variable from i and then j and then print the full loop of items in k, but it doesn't seem to do that. If you have a moment, could explain how this loop would work?

If we look at your code and mark each loop, then mark the output as well, and indent each line in terms of the loop it matches, hopefully it might help you see what's happening:

hugehairypants = ['huge', 'hairy', 'pants']
for i in hugehairypants:      # LOOP 1
    print(i)
    for j in hugehairypants:    # LOOP 2
        print(j)
        for k in hugehairypants:    # LOOP 3
            print(k)

And the output:

huge   (LOOP 1, first time)
    huge   (LOOP 2, first time)
        huge   (LOOP 3, first time)
        hairy  (LOOP 3)
        pants  (LOOP 3)
    hairy  (LOOP 2, first time)
        huge   (LOOP 3, second time)
        hairy  (LOOP 3)
        pants  (LOOP 3)
    pants  (LOOP 2, first time)
        huge   (LOOP 3, third time)
        hairy  (LOOP 3)
        pants  (LOOP 3)
hairy  (LOOP 1, first time)
    huge   (LOOP 2, second time)
        huge   (LOOP 3, fourth time)
        hairy  (LOOP 3)
        pants  (LOOP 3)
    hairy  (LOOP 2, second time)
        huge   (LOOP 3, fifth time)
        hairy  (LOOP 3)
        pants  (LOOP 3)
    pants  (LOOP 2, second time)
        huge   (LOOP 3, sixth time)
        hairy  (LOOP 3)
        pants  (LOOP 3)
pants  (LOOP 1, first time)
    huge  (LOOP 2, third time)
        huge   (LOOP 3, seventh time)
        hairy  (LOOP 3)
        pants  (LOOP 3)
    hairy  (LOOP 2, third time)
        huge   (LOOP 3, eighth time)
        hairy  (LOOP 3)
        pants  (LOOP 3)
    pants  (LOOP 2, third time)
        huge   (LOOP 3, ninth time)
        hairy  (LOOP 3)
        pants  (LOOP 3)

So loop 1 outputs the list once, loop 2 outputs the list three times, and loop 3 outputs the list nine times in total.

As a side note, we could have also altered the code to do the indentation for us:

hugehairypants = ['huge', 'hairy', 'pants']
for i in hugehairypants:      # LOOP 1
    print(i)
    for j in hugehairypants:    # LOOP 2
        print('    %s' % j)
        for k in hugehairypants:    # LOOP 3
            print('        %s' % k)

And, while sometimes it's a good idea to work things out by hand (as I did in the example output above), just so you can be sure you understand the process, we could even use counters to print out the number of times we've hit each loop, rather than figuring it out manually:

time_label = ['','first','second','third','fourth','fifth','sixth','seventh','eighth','ninth']
i_counter = 0
j_counter = 0
k_counter = 0
hugehairypants = ['huge', 'hairy', 'pants']
for i in hugehairypants:      # LOOP 1
    if i == 'huge':
        i_counter += 1
    print('%s (LOOP 1, %s time)' % (i, time_label[i_counter]))
    for j in hugehairypants:    # LOOP 2
        if j == 'huge':
            j_counter += 1
        print('    %s (LOOP 2, %s time)' % (j, time_label[j_counter]))
        for k in hugehairypants:    # LOOP 3
            if k == 'huge':
                k_counter += 1
            print('        %s (LOOP 3, %s time)' % (k, time_label[k_counter]))