<jupyter_start><jupyter_text>`for` LoopThis section introduces the sequence of data items using `list` and `range`. The `for` loop is used to iterate a sequence of data items. `for` checks the exit condition automatically therefore it is safer than `while`. 1 A Sequence of DataWhen you need to process a sequence of data items, you put them into a pair of brackets like `[item1, item2, item3, ...]`. A collection of items enclosed in a pair of brackets is called a `list`. The following are two lists:<jupyter_code>students = ['Alice', 'Bob', 'Cindy']
scores = [80, 90, 100]

print(students[0], students[1], students[2])
print(scores[0], scores[1], scores[2])<jupyter_output><empty_output><jupyter_text>The first is a list of strings. The second is a list of numbers. Each item in the list can be accessed using its location (called `index`) in the list. The syntax is `list_variable[index]`. The `index` starts from 0 up to the length, but not including the length. For a list of three elememts, the valid indexes are `0`, `1` and `2`.  2 The `range` FunctionPython has a built-in function `range` that generates a sequence of numbers. The function can take one, two, or three arguments. - `range(n)`: generate a sequence of integers in the range of `0` up to, but not including, the number `n`. For example, `range(3)` generates a seuqnce of `0`, `1` and `2`.- `range(m, n)`: generate a sequence of integers in the range of `m` up to, but not including, the number `n`. For example, `range(3, 7)` generates a sequence of `3`, `4`, `5`, and `6`.- `range(m, n, step)`, generate a sequence of integers in the range of `m` up to, but not including, the number `n`, the generate numbers increase at the specified step. For example, `range(3, 7, 2)` generates a sequence of `3` and `5`. `7` is not in the generated list because numbers biggern than or equal to `7` are excluded.It is possible to use a negative step in a `range` function to generate a list from high to low. For example, `range(3, 0, -1)` generates a list of `[3, 2, 1]`.   3 The `for` LoopThe syntax of `for` loop is as the following:```pythonfor variable_name in sequence:   statement   statement   ...```Like the decision structure, the `for` loop has two parts: a `for` clause and a code block. The `for` clause gets each element from a `sequence` that is a list or a `range` function, assigns the item to an variable and execute the code block. It completes when there is no more elements in the seuqnce. The variable used in the `for` clause is called a `target variable` because it is assigned the value of each element in the sequence in each loop iteration. Again, it is important to give it a meaningful variable name.Conceptually, it works as the following flow chart:![for](images/for.jpg)Following are two examples that print out elements in a sequence -- you use the target variable to access each element:<jupyter_code>students = ['Alice', 'Bob', 'Cindy']
for student in students:
    print(student)
print('All students are printed\n')

for item in range(3, 10, 2):
    print(f'Curent item: {item}')
print ('Printed all items')<jupyter_output><empty_output><jupyter_text>4 The List LengthThe `len` built-in function returns the number of items in a list.<jupyter_code>students = ['Alice', 'Bob', 'Cindy']
print(len(students))<jupyter_output><empty_output><jupyter_text>The following code calculate the average of a list of intgers:<jupyter_code>scores = [80, 90, 100, 60, 77, 59, 92]
total = 0

for score in scores:
    total += score

average = total / len(scores)
print(f'The average score is {average: .2f}')<jupyter_output><empty_output><jupyter_text>The above code is for demo only. In production code, there is a built-in function `sum` that can be used to calculate the total of a list of numbers. There are also built-in functions computing the minimum value `min` and maximum value `max`. You should learn [Numeric and Math Modules](https://docs.python.org/3/library/numeric.html) after you learn the basic Python syntax.<jupyter_code>scores = [80, 90, 100, 60, 77, 59, 92]
total = sum(scores)
average = total / len(scores)
print(f'The total is {total}, average is {average: .2f}, min is {min(scores)}, max is {max(scores)}')<jupyter_output><empty_output><jupyter_text>5 The Index IdiomYou can compose the `len` and the `range` functions to generate a sequence of the index numbers for a list. For the above students list, the composed function `range(len(students))` generates a sequence of 0, 1 and 2.Actually, it is an idiom in Python to use the composed function to access both the item and its index in a list. Following is an example to display students and there places in the list. For a typical business user, the index should starts from 1, not 0.<jupyter_code>students = ['Alice', 'Bob', 'Cindy']
for student in students:
    print(student)
print('All students are printed\n')<jupyter_output><empty_output><jupyter_text>As an exercise, you can write the above code using `while` loop and compare the two versions to see the differences and  pros and cons. Using f-string, you can format the output as the following:<jupyter_code># It is a good idea to give a constant a good name
PLACE_WIDTH = 5
NAME_WIDTH = 20

students = ['Alice', 'Bob', 'Cindy']

# the format modifier can use variables too !!!
print(f'{"Place": >{PLACE_WIDTH}} {"Name": >{NAME_WIDTH}}')

# Python support * for string
print('-' * PLACE_WIDTH, '-' * NAME_WIDTH)
for index in range(len(students)):
    print(f'{index + 1: >{PLACE_WIDTH}} {students[index]: >{NAME_WIDTH}}')<jupyter_output><empty_output><jupyter_text>6 Nested LoopIn the code block of a loop statement, you can have another loop statement, this is called nested loop. Conceptually it is rather simple, just treat the nested loop as a regular statement and everything becomes clear. Following is an example,<jupyter_code>numbers = [1, 2, 3]
chars = ["A", "B", "C"]

print('Outside loop')
for number in numbers:
    print('Inside number loop')
    for char in chars:
        print('Inside char loop')
        print(number, char)<jupyter_output><empty_output><jupyter_text>As you can see, the inner `for char` loop is repeated for each number in the outer `for number` loop. Practice more and you will have a better understanding.  7 ExerciseExercise 4-3: change the following `for` loop code to use `while` loop.<jupyter_code>students = ['Alice', 'Bob', 'Cindy']
for student in students:
    print(student)
print('All students are printed\n')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10301353013530136, 'fraction_numerical': 0.01583640836408364, 'mean_word_length': 4.876242095754291, 'pattern_counts': {'":': 2, '<': 37, '<?xml version=': 0, '>': 41, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '363774', 'license': 'Apache-2.0', 'n_tokens_mistral': 2016, 'n_tokens_neox': 1893, 'n_words': 929, 'path': '4-repetition-structure/for-loop.ipynb', 'repo_name': 'ying-teaching/python', 'size': '6504'}