This includes
conditional statements and loops which are common flow controls
in any programming
language.
`while` loop
------------
Executes a command
while condition
is still satisfied. |
#
from previous example
>>> while b < 10:
... print(b, end=',')
... b = b + 1
...
0,1,2,3,4,5,6,7,8,9,>>>
>>>
|
`if` statements
---------------
Most well-known
statment type in all
programming languages. There can be one or more `elif` and the `else` part is optional. `elif` is short for `else if` |
>>>
x = int(input("Please enter an integer: "))
Please
enter an integer: 42
>>>
if x < 0:
... x = 0
... print('Negative changed to zero')
...
elif x == 0:
... print('Zero')
...
elif x == 1:
... print('Single')
...
else:
... print('More')
...
|
Multiple conditions
in newlines
|
if
condition1 == condition2 or \
condition1 == condition2 or \ ... conditionN == conditionNL: ...
if
(cond1 == 'val1' and cond2 == 'val2' and
cond3 == 'val3' and cond4 == 'val4'):
do_something
|
Testing multiple
flags at once
|
#
Different ways to test multiple
#
flags at once in Python
x, y,
z = 0, 1, 0
if x
== 1 or y == 1 or z == 1:
print('passed')
if 1
in (x, y, z):
print('passed')
#
These only test for truthiness:
if x
or y or z:
print('passed')
if
any((x, y, z)):
print('passed')
|
`for` statements
----------------
Pythons's `for`
statement iterates
over items in sequences (lists or
strings) in order
of their appearance.
|
>>>
# Measure some strings:
>>>
words = ['cat', 'window', 'defenestrate']
>>>
for w in words:
... print(w, len(w))
...
cat 3
window
6
defenestrate
12
|
To modify the
sequence, loop over a
slice copy instead of looping over individual items like in the example above. |
>>>
for w in words[:]: # Loop over a slice
copy of the entire list.
... if len(w) > 6:
... words.insert(0, w)
...
>>>
words
['defenestrate', 'cat', 'window', 'defenestrate']
# looping via every items and trying to edit the sequence will make # the interpreter hang
>>>
for w in words:
... if len(w) > 6:
... words.insert(0, w)
...
#
hangs here...
|
looping backwards
|
Use range's
"step" parameter (3rd one) to specify backward movement.
>>> l = '12345'
>>>
for i in range(len(l), 0, -1):
... print(i)
...
5
4
3
2
1
>>>
|
The `range()` function
----------------------
`range()` allows
quick way to generate a
sequence of numbers. By default, start point starts with 0. |
>>>
for i in range(5): # sequence starts
with 0 and ends with 4
... print(i)
...
0
1
2
3
4
>>>
range(10)
range(0,
10) # *
>>>
list(range(10)) # you can use list()
to generate a list
[0,
1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>
|
It is possible to
specify a start point
(other than 0) as well as an end point. |
>>>
list(range(5, 10))
[5,
6, 7, 8, 9]
>>>
|
You may also use
increments (steps).
|
>>>
list(range(0, 10, 3))
[0,
3, 6, 9]
>>>
list(range(-10, -100, -30))
[-10,
-40, -70]
>>>
|
Combining
`rannge()` and `len()` can be
used to iterate over indices of a sequence. |
>>>
a = ['Mary', 'had', 'a', 'little', 'lamb']
>>>
for i in range(len(a)):
... print(i, a[i])
...
0
Mary
1 had
2 a
3
little
4
lamb
|
* A strange thing
happens if you just print a range:
>>>
print(range(10))
range(0,
10)
In many ways the
object returned by range() behaves as if it is a list, but in
fact it isn’t. It is
an object which returns the successive items of the desired
sequence when you
iterate over it, but it doesn’t really make the list, thus
saving space.
We say such an object
is iterable, that is, suitable as a target for functions
and constructs that
expect something from which they can obtain successive items
until the supply is
exhausted. We have seen that the for statement is such an
iterator. The
function list() is another; it creates lists from iterables:
>>>
list(range(5))
[0, 1,
2, 3, 4]
`break` and `continue` statements, and `else` clauses
on loops
--------------------------------------------------------------
The break statement,
like in C, breaks out of the smallest enclosing for or
while loop.
Loop statements may
have an else clause; it is executed when the loop terminates
through exhaustion of
the list (with for) or when the condition becomes false
(with while), but not
when the loop is terminated by a break statement. This is
exemplified by the
following loop, which searches for prime numbers:
>>>
for n in range(2, 10):
... for x in range(2, n):
... if n % x == 0:
... print(n, 'equals', x, '*', n//x)
... break
... else:
... # loop fell through without finding a
factor
... print(n, 'is a prime number')
...
2 is a
prime number
3 is a
prime number
4
equals 2 * 2
5 is a
prime number
6
equals 2 * 3
7 is a
prime number
8
equals 2 * 4
9
equals 3 * 3
(Yes, this is the
correct code. Look closely: the else clause belongs to the for
loop, not the if
statement.)
When used with a
loop, the else clause has more in common with the else clause
of a try statement
than it does that of if statements: a try statement’s else
clause runs when no
exception occurs, and a loop’s else clause runs when no
break occurs.
The continue
statement, also borrowed from C, continues with the next iteration
of the loop:
>>>
for num in range(2, 10):
... if num % 2 == 0:
... print("Found an even
number", num)
... continue
... print("Found a number", num)
Found
an even number 2
Found a
number 3
Found
an even number 4
Found a
number 5
Found
an even number 6
Found a
number 7
Found
an even number 8
Found a
number 9
`pass` statements
-----------------
`pass` does
nothing. It can be used to prevent
syntax errors. |
>>>
while True:
... pass
# Busy-wait for keyboard interrupt (Ctrl+C)
...
|
Also used for
minimal classes.
|
>>>
class MyEmptyClass:
... pass
...
|
Another place pass
can be used is as a place-holder for a
function or
conditional body when you are working on new
code, allowing you
to keep thinking at a more abstract
level. The pass is
silently ignored.
|
>>>
def initlog(*args):
... pass
# Remember to implement this!
...
|
Looping Techniques
------------------
When looping
through dictionaries, the key and corresponding value can
be retrieved at the
same time using the items() method.
|
>>>
knights = {'gallahad': 'the pure', 'robin': 'the brave'}
>>>
for k, v in knights.items():
... print(k, v)
...
gallahad
the pure
robin
the brave
>>>
|
You can retrieve
both index and element value of a list in a loop using
enumerate() |
>>>
for i, v in enumerate(['tic', 'tac', 'toe']):
... print(i, v)
...
0 tic
1 tac
2 toe
>>>
|
Looping over
multiple sequences can be achieve using zip()
|
>>>
questions = ['name', 'quest', 'favorite color']
>>>
answers = ['lancelot', 'the holy grail', 'blue']
>>>
for q, a in zip(questions, answers):
... print('What is your {0}? It is {1}.'.format(q, a))
...
What
is your name? It is lancelot.
What
is your quest? It is the holy grail.
What
is your favorite color? It is blue.
>>>
|
Reverses a sequence
|
>>>
for i in reversed(range(1, 10, 2)):
... print(i)
...
9
7
5
3
1
>>>
|
Sorts a sequence
|
>>>
basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>>
for f in sorted(set(basket)):
... print(f)
...
apple
banana
orange
pear
>>>
|
This changes the
original sequence during looping by making a slice
copy of the sequence first. Not making a slice copy will not change the original sequence. |
>>>
words = ['cat', 'window', 'defenestrate']
>>>
for w in words[:]: # Loop over a slice
copy of the entire list.
... if len(w) > 6:
... words.insert(0, w)
...
>>>
words
['defenestrate',
'cat', 'window', 'defenestrate']
>>>
|
More on conditions
------------------
- `while` and `if`
can contain any operators (not only comparisons)
- `in` and `not in`
checks whether a value occurs/not occur inside a sequence
- `is` and `is not`
compares if 2 mutable objects are same (e.g list)
- comparison
operators have same priority
- comparison
operators have lower priority than numerical operators
- comparisons can be
chained
e.g
a < b == c
a is less than b moreover equals c
- comparisons maybe
combined using boolean operators `and` and `or`
- outcome of
comparions may be negated with `not`
- `not` has higher
priority than `and` and `or`
- `and` and `or` are
also called "short-circuit" operators
* values are evaluated from left to right
* evaluation stops as soon as outcome is
determined
* e.g if "A" and "C"
are true but "B" is false, `A and B and C` does not
evaluate the expression C --> I
don't understadnd this!!!
* when used as a general value, the return
value of a short-circuit
operator is the last evaluated argument
- you can assign
result of comparison to a variable
* e.g
>>>
string1, string2, string3 = '', 'Trondheim', 'Hammer Dance'
>>>
non_null = string1 or string2 or string3
>>>
non_null
'Trondheim'
>>>
- assignment cannot
occur inside expressions --> need more example on this!
Comparing Sequences and other Types
-----------------------------------
Sequence objects may
be compared to other objects with the same sequence type.
The comparison uses
lexicographical ordering: first the first two items are
compared, and if they
differ this determines the outcome of the comparison; if
they are equal, the
next two items are compared, and so on, until either
sequence is
exhausted. If two items to be compared are themselves sequences of
the same type, the
lexicographical comparison is carried out recursively. If all
items of two
sequences compare equal, the sequences are considered equal. If one
sequence is an
initial sub-sequence of the other, the shorter sequence is the
smaller (lesser) one.
Lexicographical ordering for strings uses the Unicode
codepoint number to
order individual characters. Some examples of comparisons
between sequences of
the same type:
(1, 2,
3) < (1, 2, 4)
[1, 2,
3] < [1, 2, 4]
'ABC'
< 'C' < 'Pascal' < 'Python'
(1, 2,
3, 4) < (1, 2, 4)
(1,
2) < (1, 2, -1)
(1, 2,
3) == (1.0, 2.0, 3.0)
(1, 2,
('aa', 'ab')) < (1, 2, ('abc', 'a'),
4)
Note that comparing
objects of different types with < or > is legal provided
that the objects have
appropriate comparison methods. For example, mixed numeric
types are compared
according to their numeric value, so 0 equals 0.0, etc.
Otherwise, rather
than providing an arbitrary ordering, the interpreter will
raise a TypeError
exception.
No comments:
Post a Comment