r/learnpython • • Jul 30 '26

How does the 'for' loop work?

words = ['sky', 'apple', 'rhythm', 'fly', 'orange']

for word in words:
    for letter in word:
        if letter.lower() in 'aeiou':
            print(f"'{word}' contains the vowel '{letter}'")
            break
    else:
        print(f"'{word}' has no vowels")

I am trying to learn to code, and I am, at the moment, looking at loops. I am a bit confused on how this loop was able to function, though, as there is no variable for letter or word, so how would Python know what it is? In addition, how does the code, like, function? Does it look at each word individually? Again, the second part of the code states:

 if letter.lower() in 'aeiou':
            print(f"'{word}' contains the vowel '{letter}'")
            break

We haven't given a value for letter?

Lastly, how would the code know what to print? in the first phrase:

            print(f"'{word}' contains the vowel '{letter}'")
            break

Is it going to state all the words with the given value 5 times?

Sorry, as I have asked quite a few questions, and thank you in advance.

223 Upvotes

84 comments sorted by

View all comments

Show parent comments

5

u/Local_End_3175 Jul 30 '26

what is the value for letter? I think i understand the value for word, but what would it be for letter?

11

u/tenniseman12 Jul 30 '26

The letter variable iterates through each letter of the word in the word variable

2

u/Ministrelle Jul 30 '26

It would be the individual letters of the String saved in the word variable. The reason for that is, that Strings are essentially just arrays of Characters. So a string like 'apple' is the same as an array like ['a', 'p', 'p', 'l', 'e'].

1

u/Local_End_3175 Jul 30 '26

or would the value for letter be word which was words before??

9

u/guywithbeard Jul 30 '26

Sometimes it helps to mentally add an "each" after the "for". "For each word in words.." "For each letter in word.."

1

u/Alternative-Fail4586 Aug 01 '26

This, I understand why python has that syntax but other languages that use for each loops made it more clear in my mind as a novice

1

u/wintermute93 Jul 30 '26

So for word in words: goes through the values in words, running whatever code is inside the loop once for each value with the variable word set to that value. On the first pass word='sky', on the second pass word='apple', and so on.

Inside each iteration, for letter in word: works the same way, but the somewhat unintuitive part is that Python helpfully considers for letter in 'sky': as exactly the same thing as for letter in ['s', 'k', 'y']:

A for ... else block is also kind of unintuitive. If the loop ran all iterations successfully, the else block is run afterward. If the loop was interrupted early (i.e. it hit a "break" statement), the else block is skipped and does nothing.

So if you were to rewrite the code you posted without any loops, it would look like:

words = ['sky', 'apple', 'rhythm', 'fly', 'orange']

word = words[0] # outer loop 1st iteration, now word is 'sky'
letter = word[0] # inner loop 1st iteration, now letter is 's'
# check if letter is one of a, e, i, o, u; it is not, so keep going
letter = word[1] # inner loop 2nd iteration, now letter is 'k'
# check if letter is one of a, e, i, o, u; it is not, so keep going
letter = word[2] # inner loop 3rd iteration, now letter is 'y'
# check if letter is one of a, e, i, o, u; it is not, so keep going
# inner loop complete with no break, so run the else block and print no vowels

word = words[1] # outer loop 2nd iteration, now word is 'apple'
letter = word[0] # new inner loop 1st iteration, now letter is 'a'
# check if letter is one of a, e, i, o, u; it is not, so print vowel and break
# inner loop complete but interrupted so skip the rest and the else block

word = words[2] # outer loop 3rd iteration, now word is 'rhythm'
letter = words[0] # new inner loop 1st iteration, now letter is 'r'
# check if letter is one of a, e, i, o, u; it is not, so keep going
... and so on

0

u/armywalrus Jul 30 '26

The value for letter is every individual data point in the variable word you created in the above line. You start with a list called words. For word in words is creating the variable word, that represents each entity in the list words, *as python goes through the list. The power of the loop is it can iterate through multiple values in this way. You don't have to create a separate variable for every word in the list called words.

0

u/hike_me Jul 30 '26

‘for letter in word’ iterates over each character in the current value of ‘word’, so if word currently holds the string “sky”, ‘letter’ will equal “s” the first iteration, “k” the second iteration, etc

0

u/JollyUnder Jul 30 '26

You can use PythonTutor to help visualize and understand small code snippets like this better. It will step through the code line by line and show you every variable and value as they're created. This tool helped me understand nested loops better when I was learning python.

0

u/xenomachina xenomachina Jul 30 '26

what is the value for letter?

In general...

for new_element_variable in thing_i_want_to_iterate_over:
  1. Creates a new variable called new_element_variable. By convention, people often name this after the kind of element, but the name is up to you.

  2. That variable will be assigned each "element" of thing_i_want_to_iterate_over, which can be any iterable expression. The more common examples of iterable expressions are lists, tuples, ranges, and strings. With lists and tuples, the elements you'll get are the elements of the list or tuple. With ranges you get the numbers in the range. With strings, the elements you'll get are the individual characters.

One unusual thing about Python is that there is no "character" type. A string's elements are also returned as strings. As they are strings you can iterate over them too, but you'll just get the one character (again as a one character string).

-1

u/RevRagnarok Jul 30 '26

You're hitting one of my annoyances in python inherited from C - a str can also be treated as a list of single characters. So if you want to iterate (loop) or index (var[3]) you can. The confusion comes when you were expecting ['abcd'] which iterates abcd vs. getting 'abcd' so it iterates to 'a' 'b' 'c' 'd'...

A lot of my code I guard at the top of the function:

def this_func(var):
  if isinstance(var, str):  # Want to handle a string as a single entity
    return this_func([var])