Recommended reading:
[1] C. Horstmann: Python for everyone
[2] Python tutorial: https://docs.python.org/3/tutorial/
int
, float
, str
, type
str
, tuple
, list
, set
, dict
del
if
, elif
, else
while
, for
, enumerate
, zip
, itertools
, iteratorsdef
, lambda
, return
, scope*args
, positional arguments**kwargs
, keyword arguments (with default values)dir
, help
import
, from x import y as z
int
, float
, str
type
and type conversionYou can check the type of almost any value
type(3.14)
type('Hello World')
type(100)
type(True)
The types float
, int
, str
, bool
, etc. have the type: type
type(int)
x = int('123')
type(x)
x = str(45.3)
type(x)
print(x, type(x))
But only if there the conversion makes sense
x = int('Carl')
str
tuple
, list
, set
, dict
del
str
¶a = 'Hello World'
b = "Hello World"
c = """Hello World"""
d = '''Hello World'''
Immutable /ɪˈmjuːtəb(ə)l/:
unchanging over time or unable to be changed
a = 'Hello World'
a[0] = 'Y'
a = 'Hello\nWorld'
print(a.upper())
', '.join(s for s in dir('') if not '__' in s) # Brain-teaser! :)
tuple()
, ()
¶x = (3.14, int, 'John')
x = 3.14, int, 'John' # paranthesis are optional
print(x)
', '.join(s for s in dir(tuple()) if '__' not in s)
help(tuple().index)
t = 'A', 'B', 'C'
t.index('C')
x = (3.14, int, 'John')
x[0] = 3.1415
x = 3.14, int, 'John'
a, b, c = x
print(a)
list
, set
and dict
x = ['Hello', 'Foo', 'World']
a, b, c = x
print(a, c)
x = {1, 2, 2}
a, b = x
print(a, b)
x = {'John': 37, 'Sara': 25, 'Lisa': 45}
a, b, c = x.items()
print(a, c)
list()
, []
¶tuple
)x = [43, 10, 15]
len(x)
y = ['Hello', 'World']
z = [[1, 2, 3], [4, 2], [9, 4, 2]]
z[2] = 41
print(z)
list
methods¶', '.join(s for s in dir(list()) if '__' not in s)
help(list().sort)
x = [4,67,2,10]
x.sort()
print(x)
[]
x = [43, 10, 15]
x[1]
-1
is the index of the last elementx[-1]
start:end:increment
*
Matlab Python x(a:b:c) ~ x[(a-1):c:b] end ~ -1 or nothing:
- True for single index
x(end) ~ x[-1]
- But `-1+1 = 0` so when using slicing, the syntax is to leave it out
x(1:2:end) ~ x[::2] x(7:end) ~ x[6:]
a:b
$= [a,b)$x = ['my', 'short', 'list', 'of', 'strings']
x[0:2]
x[1:]
x[:1]
x[:]
x[0::2]
x[0:2:3]
x[::-1]
set()
, {}
¶x = {1, 2, 3, 2, 7, 2, 3, 2, 6}
print(x)
x.add(8)
print(x)
y = x.intersection({1, 4, 5, 6, 10})
print(y)
set
-methods', '.join(s for s in dir(set()) if '__' not in s)
help(set().intersection)
A = ['Ada', 'Beda', 'Emil', 'Emilia']
B = ['Ada', 'Emilia', 'Eva', 'Greta']
s = set(A).intersection(B)
l = list(s)
print(l)
dict()
, {}
¶
x[key] = value
representing the mapping of $key \to value$
x = {'John': 37, 'Sara': 25, 'Lisa': 45}
x['Lisa']
It is very common to create an empty dictionary and
add new entries as required (e.g. values are read from a file)
x = dict() # or x = {}
x['John'] = 37
x['Sara'] = 25
x['Lisa'] = 45
print(x['John'])
in
and not in
print( 'Lisa' in x )
print( 'Jeff' not in x )
keys
, values
, or (key,value)
pairsprint( x.keys() )
print( x.values() )
print( x.items() )
del
¶del
can be used to remove elements in list
, dict
x = [4,5,6,4,3,5,1]
del x[3:]
print(x)
x = {'John': 37, 'Sara': 25, 'Lisa': 45}
del x['John']
print(x)
There are also methods for "consuming" elements, like .pop
sara_age = x.pop('Sara')
print(sara_age)
print(x)
del
can also be used to remove an objectx = 10
del x
print(x)
if
, elif
, else
while
, for
, enumerate
, zip
, itertools
, .items()
type(enumerate(['A', 'B', 'C']))
if
, elif
, else
¶True
, False
if False:
print('Stuff here')
elif True:
print("Let's print")
print('many lines')
else:
print('Good bye!')
a = 1
x = 1 if a > 2 else
print(x)
:
require a following indented blockMatlab conditionals
if x
f();
elseif y
g();
end
for x = y
disp('foo');
end
if q
end
Python conditionals
if x:
f()
elif y:
g()
for x in y:
print('foo')
if q:
pass # no-operation, needed to avoid syntax errors
in
, not
, and
, or
print( 1 in [1,2,3] )
print( 7 not in (4,3,5) )
print( 'W' in 'World' )
print( 6 != 5, 6 == 5 )
print( 6 >= 5, 6 <= 5 )
print( 6 > 5, 6 < 5 )
print( True or False )
print( True and False )
print( not True )
while
, break
, continue
¶
while condition: do_stuff
- `break` and `continue` work as in Matlab
- Q: What is printed below?
x = 0
while x < 10:
x = x + 1
if x == 3:
continue
print(x, end=', ')
if x > 6:
break
for
¶tuple
, list
, set
, dict
, etc.foo = ['This', 'is', 'a', 'list']
for x in foo:
print(x)
range(start, end+1, step)
iterator over integer rangesrange(a, b, c) ~ a : c : (b-1)
for i in range(5):
print(i, end=', ')
for i in range(1, 10, 2):
print(i, end=', ')
for
... dict
¶foo = {'John': 37, 'Sara': 25, 'Lisa': 45}
for x in foo:
print(x)
foo = {'John': 37, 'Sara': 25, 'Lisa': 45}
for x in foo.items():
print(x)
for key, value in foo.items():
print(key, "is", value, "years old")
enumerate
and zip
¶enumerate
foo = ['This', 'is', 'a', 'list', 'of', 'strings']
for i, x in enumerate(foo):
print('counter is', i, 'and value is', x)
zip
zip
"zips" the sequences into a sequence of tuplesx = [3, 7, 4, 9, 3, 0]
y = "qwerty"
z = {1, 2, 3}
for i, c, i2 in zip(x, y, z):
print(i, c, i2)
zip
doesn't actually create a listz = zip(x,y)
print(z)
print(type(z))
list
z = list(zip(x,y))
print(z)
if
, while
, for
etc. can all be written on a single lineif 3 > 0: print('It works!')
for s in ['This', 'works', 'too!']: print(s, end=' ')
l = list()
for i in range(5):
l.append(i**2)
print(l)
l = [k**2 for k in range(5)]
print( l )
l = [k**2 for k in range(10) if k % 2 != 0]
print( l )
set
and dict
d = {k**2 for k in range(10)}
print(d)
l = ['John', 'Jeff', 'Carl']
d = { key : idx**2 for idx, key in enumerate(l) }
print(d)
d = {}
for idx, key in enumerate(l):
d[key] = idx**2
print(d)
+, -, *, /, **
list
, tuple
, str
+=, -=, *=, /=, //=
==, is, in, >, <, >=, >=
>>, <<, &, |, ^
print('4 + 3 =', 4 + 3)
print('4 - 3 =', 4 - 3)
print('4 * 3 =', 4 * 3)
print('4 / 3 =', 4 / 3)
a ** b
$= a^b$a // b
$= \lfloor a/b \rfloor$a % b
$= a \,\text{mod}\, b$print('5 ** 3 =', 5 ** 3)
print('5 // 3 =', 5 // 3)
print('5 % 3 =', 5 % 3)
a / b
is floating point divisiona // b
is integer divisiona / b
is integer division (unexpected!?)a / float(b)
is floating point divisiona / b
can be made floating point division byfrom __future__ import division
Here: Python 3
4 / 3
4 // 3
x = 1
x += 2 # x = x + 2
x *= 3 # x = x * 3
x /= 4 # etc.
print(x)
x = 1
x //= 2
print(x)
a = 0b101001
b = 0b011100
print('a = {:d} = 0b{:06b}'.format(a, a))
print('b = {:d} = 0b{:06b}'.format(b, b))
&
, or |
, xor ^
a = 0b101001
b = 0b011100
print('a & b = 0b{:06b}'.format( a & b ))
print('a | b = 0b{:06b}'.format( a | b ))
print('a ^ b = 0b{:06b}'.format( a ^ b ))
>>
and <<
print("41 >> 1 =", 41 >> 1)
print("41 << 1 =", 41 << 1)
X >> 1
shifts the bits one step to the right
$$41 >> 1 = 101001_b >> 1 = 010100_b = 2^4 + 2^2 = 20$$
This is equal to integer division by 2, X >> 1 == X // 2
In general: a >> b == a // (2**b)
string
'Hello World' * 3
'Hello' + ' ' + 'World'
list
, tuple
[1, 2, 3] * 3
(1, 2, 3) + (4, 5)
def
return
args
, positional argumentskwargs
, keyword arguments (with default values)*args
, **kwargs
, positional and keyword argument expansiondef
¶def print_value(x):
print('The value is:', x)
print_value(13)
return
¶def my_sum(a, b):
return a + b
print(my_sum(1, 2))
tuple
expansion (as advertised)def multi_return_function(x):
return x, x**2, x**3
x = multi_return_function(3)
print(x)
a, b, c = multi_return_function(3)
print('a = ', a, ', b = ', b, ', c = ', c, sep='')
a, b = multi_return_function(3)
def my_function(a, b=2, c=3): # b and c have default values and are optional
return a + b + c
a=1, b=2
and c=3
)print(my_function(1, 2, 3))
print(my_function(1, 2))
print(my_function(1))
print(my_function(a=1, b=2, c=3))
print(my_function( 1, b=2, c=3))
print(my_function( 1, 2, c=3))
print(my_function( 1, c=3, b=2))
print(my_function( 1, b=2))
print(my_function( 1, c=3))
print(my_function(a=1, c=3))
my_function(a=1, 2, 3) # Not OK!
my_function(1, b=2, 3) # Not OK!
list
and tuple
to positional arguments using the *
operatordef my_sum(a, b, c):
return a + b + c
x = [2, 3, 4]
s = my_sum(*x) # Uses: "a, b, c = x"
print(s)
dict
**
operatordef pet_info(name, kind=None, owner=None):
"""Returns a string summarizing the info on the pet."""
out = name
if kind is not None: out += ' is a ' + kind
if owner is not None: out += ' owned by ' + owner
out += '.'
return out
pets = [
dict(name='Snoopy', kind='dog', owner='Charlie'),
dict(name='Garfield', kind='cat', owner='Jon'),
dict(name='Bamse', kind='bear'),
]
for pet in pets:
print(pet_info(**pet)) # Expand dict to key-word arguments
def my_general_argument_function(*args, **kwargs):
print('Got positional arguments:', args)
print('Got key-word arguments:', kwargs)
my_general_argument_function(
'one', 'argument', 'at', 'a', 'time',
key='words', are='very', important='!')
c = 123
def sum_1(a):
return c + a
print(sum_1(1))
def sum_2(a):
c = 14 # c is a local variable (different from c above)
return c + a
print(sum_2(1))
print(c) # c, in the outer scope is unchanged
def sum_3(a):
c += 17 # no modification of variables from the outer scope
return c + a
print(sum_3(1))
lambda
functions@(x) x^2
def axpy(a, x, y): # trivia: axpy is a standard name for a*x + y (in linear algebra packages)
return a*x + y
print(axpy(2, 3, 4))
axpy_lambda = lambda a, x, y : a*x + y
print(axpy_lambda(2, 3, 4))
print(type(axpy), type(axpy_lambda))
def add_me(a, b): return a + b
def mul_me(a, b): return a * b
def div_me(a, b): return a / b
functions = [add_me, mul_me, div_me]
for f in functions:
print(f(1, 2))
a = 10
b = a # b is a new int variable
b += 1
print(a, b)
list
, dict
etc. are referencesa = [10]
b = a # b is a reference to the list a
b[0] += 1
print(a, b)
x = [1, 2, 3] # Create a list object and binds x to that object.
y = x # Binds y to that same object x
y += [4, 5] # += for lists means "append to list"
print(x)
x = [1, 2, 3] # Create a list object and bind x to that object.
y = x # Bind y to that same object
y = y + [4, 5] # Create a new object from the list, use + list operation and re-bind y to that new object
print(x)
x = [1, 2, 3] # Create a list object and bind x to that object
z = (x, x) # Create a tuple object which contains references which are bound to the same object
print('1:', z)
x += [4, 5] # Append to list
print('2:', z)
x = [7, 8] # Rebind name x to a new list
print('3:', z)
z
has actually not changed (tuples are immutable)x = [1, 2, 3]
y = [x, x, [7, 8, 9]]
print(y)
What will happen if we do:
y[0] = [4, 5, 6]
print(x)
print(y)
The equal sign is the "rebind variable" operation!
To really make a copy, use the slice :
, or the .copy()
method
x = [1, 2, 3]
y = x[:]
y += [4, 5]
print(x, y)
x = [1, 2, 3]
z = x.copy()
z += [6, 7]
print(x, z)
def foo(x):
x[0] = 42
y = [1, 2, 3]
foo(y) # This means foo(x = y), and x = y behaves as described earlier
print(y)
=
is variable name rebinding,x
was bound to previously.def foo(x):
x = [4, 5, 6]
y = [1, 2, 3]
foo(y)
print(y)
import numpy
numpy.sqrt(5)
import numpy as np
np.sqrt(5)
Example: Solve $x^2 - 1 = 0$ numerically
This is colloquially called: "Root solving"
from scipy.optimize import root
root(lambda x: x**2 - 1, x0=0.1)
from scipy.optimize import root as scipy_root
res = scipy_root(lambda x: x**2 - 1, x0=0.1)
print(res.x)
Using the wildcard, you import everything in that scope
from numpy import *
but this practice is discouraged!! Why?
numpy
module contains many functions, e.g. a function called all
.all
is defined in the program before the wildcard import, it is lost!def all(): return 'Hi all!'
print(all())
from numpy import *
print(all())
Examples:
from datetime import datetime
print(datetime.now())
from itertools import permutations
for pair in permutations(['A', 'B', 'C'], 2):
print(pair, end=', ')
from multiprocessing import Pool
def my_calc(x): return x*x
p = Pool(4)
l = p.map(my_calc, [1, 2, 3, 4, 5, 6, 7, 8, 9])
print(l)
PDF versions of the manuals for:
will be available on the exam. Check them out!
help
¶help
is a built in help functionhelp
on most things, functions, libraries, variableshelp(len)
help
will show this documentationdef my_sum(a, b):
"""The sum of two numbers.
Parameters
----------
a : int
First number
b : int
Second number
Returns
-------
int
Sum of a and b
"""
assert( type(a) == int )
assert( type(b) == int )
return a + b
help(my_sum)
x = 123 + /34
132/0
x = [1,2,3]
x[8]
There are many ways to use and interact with Python
.py
on the command line, using the python
interpreterpython
interpreteripython
interpreterDemo!
PyCharm
, perfect for developing GUI applications!We warmy recommend PyCharm
for learning in this course! (the free version)
(It is possible to apply for a "full" version as a student)