Control Flow

As with other programming languages Python uses a number of control-flow elements which includes loops and conditionals. Control statements can be put into the following categories

Selection

if, if-else
parrot = "Norwegian Blue"
letter = input("Enter a character")

if letter in parrot:                                        # could use not in
    print("Give me an {}, Bob".format(letter))
else:
    print("I don't need that letter")
if-elif-else
# same as (age >= 18) and (age < 21), dont need brackets but makes it easier to read
if 18 <= age < 21:                   
    print("You are old enough to vote but not drive a HGV")
elif age >= 21:
    print("You are old enough to vote and drive a HGV")
else:
    print("Please come back in {0} years and then you can vote and drive a HGV".format(18 - age))

Iteration

while loop
i = 0
while i < 10:
    print("{}".format(i), end=', ')
    i += 1

print("\n-------------------------------------------------------------")
available_exits = ['east', 'north east', 'south']

chosen_exit = ''
while chosen_exit not in available_exits:
    chosen_exit = input("Please choose a direction: ")
    if chosen_exit == 'quit':
        print("Game Over!")
        break
else:
    print("aren't you glad you got out of there!")
for loop
for state in ["not pinin", "no more", "a stiff", "bereft of life"]:
    print("This parrot is " + state)
    
for number in [1, 2, 3, 4, 5]:
    print("Number is " + number)

somelist = [(1, 2), (3, 7), (9, 5)]
result = 0
for x, y in somelist:                             # we loop through a tuple
    result = result + (x * y)
    
Note: I will discuss ranges in more detail later
    
Loop Functions
Range
for i in range(1, 20):
    print("i is now {}".format(i))

x = [1, 3, -7, 4, 9, -5, 4]
for i in range(len(x)):
    if x[i] < 0:
        print("Found a negative number at index ", i)
    
Note: Given a number n, range (n) returns a sequence 0,1,2...n. It it often used with len command
Enumerate
x = [1, 3, -7, 4, 9, -5, 4]
for i, n in enumerate(x):                         # i is the index in the list, n is the value
    if n < 0:
        print("Found a negative number at index ", i)
    
Note: You can combine tuple unpacking with the enumerate function to loop over both the items and their index.
Zip
x = [1, 2, 3, 4]
y = ['a', 'b', 'c']
z = zip(x, y)
list(z)                             # results in [(1, 'a'), (2, 'b'), (3, 'c')]

Note: Sometimes, it’s useful to combine two or more iterables before looping over them. The zip function takes the corresponding elements
from one or more iterables and combines them into tuples until it reaches the end of the shortest iterable
Comprehensions
x = [1, 2, 3, 4]
x_squared = [item * item for item in x]
x_squared                                             # results in [1, 4, 9, 16]

x = [1, 2, 3, 4]
x_squared = [item * item for item in x if item > 2]
x_squared                                             # results in [9, 16]

Note: The pattern of using a for loop to iterate through a list, modify or select individual elements, and create a new list or dictionary
is very common. This sort of situation is so common that Python has a special shortcut for such operations, called a comprehension. You
can think of a list or dictionary comprehension as a one-line for loop that creates a new list or dictionary from a sequence
Greater expressions
x = [1, 2, 3, 4]
x_squared = (item * item for item in x)

# x_squared             is a generator object  at 0x102176708>
for square in x_squared:
    print(square,)                                    # results in 1 4 9 16
    
Note: A generator expression looks a lot like a list comprehension, except that in place of square brackets, it uses parentheses

Boolean values and Expressions

Python has a Boolean object type that can be set to either True or False. Any expression with a Boolean operation returns True or False. The following boolean rules apply

There are comparison and Boolan operators

Comparison
if 0 < x and x < 10:
    ...
    
if 18 <= age < 21:      # same as (age >= 18) and (age < 21), dont need brackets but makes it easy to read
    print("You are old enough to vote but not drive a HGV")
elif age >= 21:
    print("You are old enough to vote and drive a HGV")
else:
    print("Please come back in {0} years and then you can vote and drive a HGV".format(18 - age))
    
i = 0
while i < 10:
    print("{}".format(i), end=', ')
    i += 1
Boolean Operators
[2] and [3, 4]                   # results in [3, 4]
[] and 5                         # results in []
[2] or [3, 4]                    # results in [2]
[] or 5                          # results in 5

x = [0]
y = [x, 1]
x is y[0]                        # results in True

x = [0]
x is y[0]                        # results in False

x == y[0]                        # results in True