library(reticulate) # to use python in RStudio
library(tidyverse) # data wrangling and plotting with R
R code chunks are in light pink, while python in light blue.
For loops are for when we have known number or sequence of iterations we would like to perform. We could iterate through strings, lists, tuples, dictionaries, or within a range.
While loops are for when we want to repeat a process until certain threshold is met.
We are more likely to use for loops than while loops in practice. And we can always alter interations of a for loop using conditional statements.
Small tips
statement = 'I can work in '
for i in statement: # for each character in the string
print(i)
## I
##
## c
## a
## n
##
## w
## o
## r
## k
##
## i
## n
##
language = ['R','Python','Julia']
for i in language: # for each item in the list
print(f'{statement}{i}!')
## I can work in R!
## I can work in Python!
## I can work in Julia!
We can create a new list that contains the concatenated items as follows using for loop.
ml=[]
for i in language:
ml.append(statement+i)
ml
## ['I can work in R', 'I can work in Python', 'I can work in Julia']
Worth noting that the same task can be done using list comprehension in one line, which is really concise and convenient!
ml = [statement + i for i in language]
ml
## ['I can work in R', 'I can work in Python', 'I can work in Julia']
We can easily use comprehension with dictionaries too
md = {x : x**2 for x in range(1,10)}
md
## {1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
We can also add conditions in comprehension. In the following example, we limit x to be divisible by both 2 and 3.
md = {x: x**2 for x in range(1,20) if not (x%2 or x%3)}
md
## {6: 36, 12: 144, 18: 324}
enumerate with listsNormally for lists, we are mainly interested in its items. But sometimes if we are also interested in the index, enumerate() function can be used.
ml = [1,2,3,4,5]
for idx, item in enumerate(ml):
print(f'No. {idx} item: ', item)
## No. 0 item: 1
## No. 1 item: 2
## No. 2 item: 3
## No. 3 item: 4
## No. 4 item: 5
mt = (0,1,2,3,4,5)
mySUM = 0
for i in mt: # for each item in the tuple
mySUM += i # concise way of saying mySUM = mySUM + i
print(mySUM)
## 0
## 1
## 3
## 6
## 10
## 15
For loop with dictionaries is a bit different because dictionaries have key: value pairs. When iterating with a dictionary, we need to decide what we want, the key, the value or both.
md = {'FirstName': 'John', 'LastName': 'Doe', 'Age': 35}
for k, v in md.items(): # items() method extracts both keys and values
print(f'{k}: {v}')
## FirstName: John
## LastName: Doe
## Age: 35
for k in md.keys(): # keys() method extracts keys only
print(f'The key is {k}')
## The key is FirstName
## The key is LastName
## The key is Age
In a dictionary, we could have more complex values, say lists, tuples or dataframes.
md2 = {'10s': (10,11,12),'20s': (20,21,22)}
In the above dictionary, we have tuples as values. And we can iterate through each keys and then items in each tuple too.
for k, t in md2.items(): # iterate through each key:value pair
print(f'Shwoing {k}: ', end = ' ') # space rather than new line at the end
for i in t: # iterate through each tuple
print(i, end = ' ')
print() # add a new line
print(30*'-') # add a dashed line
## Shwoing 10s: 10 11 12
## ------------------------------
## Shwoing 20s: 20 21 22
## ------------------------------
For loops in R are quite similar to those in Python.
mv <- c(0:5) # create a vector
mySUM <- 0
for (i in mv) { # for each item in the vector
mySUM = mySUM + i # see note below about modifying objects in place
print(mySUM)
}
## [1] 0
## [1] 1
## [1] 3
## [1] 6
## [1] 10
## [1] 15
Also for anyone who is interested, we could also do += sort of operation in R with the inplace package. Here is how
In addition to iterating through strings, lists, tuples and dicctionaries as demonstrated above, a for loop could also iterate through a range. Follows pls see how this can be used to replicate the example with a tuple above. Note that when constructing a range object, the starting integer is included, while the ending integer is not. Therefore, range(6) in the following example includes a sequence from 0 to 5.
mySUM=0
for i in range(6): # range: 0 to 5 by 1
mySUM += i
print('total: ', mySUM)
## total: 0
## total: 1
## total: 3
## total: 6
## total: 10
## total: 15
We can define a range object by specifying the staring integer, ending integer and the interval.
for i in range(2,11,2): # range: 2 to 10 by 2
print('index: ', i)
## index: 2
## index: 4
## index: 6
## index: 8
## index: 10
For a more interesting and complex example of for loop in range(), please click here.
The while loop is helpful when we want to continue a process until certain threshold is met. For example, say we have an infectious disease with R0 = 12, let’s use the while loop to demo how it can grow to over 10K cases.
# say we have only 1 case at day0
Total = 1
Days = 0
# the while loop:
while Total < 10000:
Total *= 12 # r0 = 12
Days += 1
print(f'Day{Days}: {Total} cases')
## Day1: 12 cases
## Day2: 144 cases
## Day3: 1728 cases
## Day4: 20736 cases
print('10,000 cases reached!')
## 10,000 cases reached!
Commands are available in Python for us to break out of a loop or modify iterations. As follows please see examples with two common commands for such purposes, else and break.
* for loops: when the sequence has been exhausted
* while loops: when the while condition has become false
for i in range(1,4,1): #1,2,3
print(f'i={i}')
else:
print(f'else executed when i={i}')
## i=1
## i=2
## i=3
## else executed when i=3
mySum = 1000000
while mySum > 100:
mySum /=10
print(f'mySum is {mySum}')
else:
print(f'mySum is {mySum} and the minumum has been reached')
## mySum is 100000.0
## mySum is 10000.0
## mySum is 1000.0
## mySum is 100.0
## mySum is 100.0 and the minumum has been reached
* normally used in nested loops
* to terminate the closest enclosing loop
for i in range(1,8,3): #1,4,7
sum_j = 0
for j in range(4):
sum_j += j
if i < sum_j:
break
print(f'i={i} is no less than the sum of j={sum_j}')
print('inner loop iteration')
print('//break out of the inner loop//\n')
## i=1 is no less than the sum of j=0
## inner loop iteration
## i=1 is no less than the sum of j=1
## inner loop iteration
## //break out of the inner loop//
##
## i=4 is no less than the sum of j=0
## inner loop iteration
## i=4 is no less than the sum of j=1
## inner loop iteration
## i=4 is no less than the sum of j=3
## inner loop iteration
## //break out of the inner loop//
##
## i=7 is no less than the sum of j=0
## inner loop iteration
## i=7 is no less than the sum of j=1
## inner loop iteration
## i=7 is no less than the sum of j=3
## inner loop iteration
## i=7 is no less than the sum of j=6
## inner loop iteration
## //break out of the inner loop//
Of course, we can use break and else together. The following example uses an outer loop plus an inner loop to identify prime numbers from 1 to 25. The else clause is executed if, and only if, the inner loop terminates normally. In other words, if the inner loop invokes break, which means a divisor was found, the else clause will not be executed. The example is posted by Dave Wade-Stein in this thread on Quora entitled What are the downsides of the python programming language?
for num in range(2, 26):
for check in range (2, num):
if num % check == 0:
break
else:
print(num, 'is prime')
## 2 is prime
## 3 is prime
## 5 is prime
## 7 is prime
## 11 is prime
## 13 is prime
## 17 is prime
## 19 is prime
## 23 is prime
We could also use pass as a placeholder when we are not sure what to do under certain condition yet.
for i in range(1000, 1500):
if not i%67: # find and print the first integer that can be divided by 67
print(i)
break
else:
pass # pass
## 1005