Python has a bunch of different ways of doing loops that come in handy at different times.
Let's start with the most basic: the while loop. This is quite like you'd be used to in other languages; you just have a boolean expression that keeps the loop going if it evaluates to True. For example, if we wanted to loop until we found a number that was divisible by both 3 and 7, we'd write the following loop:
x = 1
while x%3 != 0 or x%7 != 0:
x += 1
print(x)
21
Of course, the while loop can be used for anything. So we can use it in a scenario where we want to loop up to a particular range, even though a for loop is technically better than that. For example, an equivalent to the C++ or Java loop
for (int i = 10; i < 100; i+= 2) {
could be written as
i = 10
while i < 100:
# Do stuff
i += 2
Actually, a quick note here that python unfortunately does not have the var++ notation.
i++
File "/tmp/ipykernel_9831/1074925126.py", line 1 i++ ^ SyntaxError: invalid syntax
So if you wanted to increment by 1, you'd have to say i += 1
i += 1
If you want to stop here, that's fine! I don't really care if you do things the most "pythonic way," because this course is more about data structures than python style. But if you want to make your code more succinct by using more appropriate loops, read on
The for loop in python is more flexible than you're probably used to in other languages, and it may take a moment to really understand what's going on behind the scenes. But let's start with a scenario that's similar to a for loop that you'd do in Java or C++. If you had the code
for (int x = 174; x < 271; x+=10) {
the python equivalent would be
for x in range(174, 271, 10):
print(x, end=' ')
174 184 194 204 214 224 234 244 254 264
If you only want to increment by 1 every time, you can omit the third parameter to range
for x in range(5, 10):
print(x, end=' ')
5 6 7 8 9
And if you want to start at 0, you can omit the first parameter
for x in range(8):
print(x, end=' ')
0 1 2 3 4 5 6 7
But as it turns out, there's a lot more you can do with for loops in python. For example, traditional way of looping through an array in Java would look like
for (int i = 0; i < arr.length; i++){
You can certainly follow this pattern in python using
arr = [1, 7, 4, 2, 7, 1, 4, 7, 7]
for i in range(len(arr)):
print(arr[i], end=' ')
1 7 4 2 7 1 4 7 7
But notice how we only ever use the variable i to index the array, and we're going through the entire array here. A more "pythonic" way to do this is with a for loop that doesn't store an index directly, but which simply loops through the elements in sequence:
for x in arr:
print(x, end=' ')
1 7 4 2 7 1 4 7 7
So if you don't actually need to use the array index for anything and you just need to loop through some elements of a collection in sequence, this syntax is much more succinct.
If you do want to keep track of an index, there's a slightly more "pythonic" way of doing it using something called "enumerate"
for i, x in enumerate(arr):
print(i, x)
0 1 1 7 2 4 3 2 4 7 5 1 6 4 7 7 8 7
In this case, the loop actually loops through two variables at once: the index i and the element x of the array. This saves you the ugly syntax of having to actually index the array, which can make code much cleaner. But you still know what the index is
If you have a list of tuples, you can write a really slick loop to unpack the elements of the tuple directly without having to index anything. For example
creatures = [("chris", 33), ("celia", 32), ("theo", 9), ("layla", 10)]
for name, age in creatures:
print(name, age)
chris 33 celia 32 theo 9 layla 10
If you have two parallel arrays, you can turn them into an array of tuples using the python command zip
. For example
names = ["chris", "celia", "theo", "layla"]
ages = [33, 32, 9, 10]
print(list(zip(names, ages)))
[('chris', 33), ('celia', 32), ('theo', 9), ('layla', 10)]
(Side note: I had to put the list()
around the zip because zip actually returns an iterator, which only returns items in sequence when we ask it to)
Putting it all together, we can loop through two arrays in parallel with
for name, age in zip(names, ages):
print(name, age)
chris 33 celia 32 theo 9 layla 10
And if we want to get really fancy and pythonic, we can also use enumerate
to keep track of our index as we go
for i, (name, age) in enumerate(zip(names, ages)):
print(i, name, age)
0 chris 33 1 celia 32 2 theo 9 3 layla 10
Just a reminder that you can accomplish all of this with more traditional C++/Java-esque approaches:
for i in range(len(names)):
print(i, names[i], ages[i])
0 chris 33 1 celia 32 2 theo 9 3 layla 10
But oftentimes the code ends up looking nicer inside the loop if we don't have to throw array indexing in everywhere