python basic types, syntax, loops, lists
sections 4-7 from the “Programming with Python” software carpentry:
- loops
- lists
- using data from multiple files
- making choices
concepts summary
basic types
int 14
,
float 14.123
,
string "hello"
, bool (True
or False
), None,
complex 3+0.5j
, also NoneType (None
).
int
s and float
s are fundamentally different in how they are coded.
consequence: never test for exact equality of float
s.
1.0/3.0 == 1.0 - 2.0/3.0 # False!!
1.0/3.0
1.0 - 2.0/3.0
to convert: int
, float
, str
, bool
, and string formatting:
bool(0)
bool(0.0)
bool(0.5)
bool(1.0/3.0 - (1.0 - 2.0/3.0)) # no!!!
int(4.9)
"%s %s hello %s" % (5, 5.8, "5")
"%d %d %d world" % (5, 5.8, int("51"))
"%.2f %.2f %.1e" % (5, float(5.8), float("51.2"))
"{} hello {} world {}".format(5, "5.8", 51.2)
"{:.2f} hello {:+} world {:.1e}".format(5, 5.8, 51.2)
-
to store multiple elements:
list[10,20]
, tuple(10,20)
, dictionary/hash{"blue":10, "green":20}
, setset([10,20])
-
a list of lists is not the same as an array.
[1,2]
to create a list.
mutable vs immutable objects
lists are mutable:
names = ['Newton', 'Darwing', 'Turing'] # typo in Darwin's name
names[1] = 'Darwin' # correct the name
print('final value of names:', names)
strings, numbers, tuples are immutable:
name = 'Darwin'
print("letter indexed 0:", name[0])
name[0] = 'd' # error!
name = "darwin"
name
a = (13,4)
print(a)
a[1] = 100 # error!
How b=a
and changes to b
can cause (or not) changes to a
:
a = "Darwin"
b = a
print("b=",b)
b = "Turing" # does not change a, because a has immutable value
print("now b=",b,"\nand a=",a)
a = [10,11]
b = a
b[1] = 22 # changes the value that b binds to, so changes a too
print("b=", b, "\nand a=",a)
c = [a,a] # list of lists. Not numpy array!
print(c)
a[0] = -5
print(c) # aahh!!
b = a.copy() # various alternative options
b = list(a)
import copy
a = [10,11]
b = copy.copy(a)
b[1] = 22 # changes the value that b binds to, does not change a
print("b=", b, "\nand a=",a)
deep copy versus simple (shallow) copy:
a = [[10,11],[20,21]]
print(a)
b = copy.copy(a)
b[0][0] = 50
print("b=",b,"and a=",a)
b[0] = [8,9]
print("b=",b,"and a=",a)
b = copy.deepcopy(a)
print("now b is back to a: ",b)
b[0][0] = 8
print("b=",b,"and a=",a)
Functions that operate on mutable objects can change them in place: this is a huge deal!
def add1_scalar(x):
"""adds 1 to scalar input"""
x += 1
print("after add1_scalar:",x)
def add1_array(x):
"""adds 1 to the first element of array input"""
x[0] += 1
print("after add1_array:",x)
help(add1_scalar)
# add1_scalar? # in interactive session
a=5; print(a)
add1_scalar(a)
print("and now a =",a) # a was not modified because it is immutable
b=[5]; print(b)
add1_array(b)
print("and now b =",b) # b was modified in place because it is mutable: array
linked to “namespace” concept, and how arguments are passed to functions
conclusion: functions can change mutable arguments in place:
- beware
- opportunities to save a lot of memory (and time)
syntax
:
to end starting lines, indentation to define blocks
for xxx in collection:
command
command
if condition:
command
elif another_condition: # optional
command
else: # optional
command
command_still_in_for_loop
important concepts:
- binding of a name
- scope of variables
- local namespace
conditions (making choices)
==
, <
, >
, not
, and
, or
.
anything other than False
, 0, None
, empty string or empty list
is considered True
in a boolean context.
try this:
a = None # try again with a = "abc", "", [1,2,3], [], True, False, 0, 1, 18
if a:
print("a was true")
else:
print("a was false")
very cool: and
and or
are short-circuit operators:
- false
and
whatever = false, so why evaluate this “whatever” - true
or
whatever = true, so why evaluate “whatever”?
example use, where “whatever” is not even a boolean:
num = -3 # change this to 5, say, to see what happens
num > 0 or print("num should be positive, but here it's" + str(num))
tuples
tuples are immutable , unlike lists. useful for
- array sizes:
(60,40)
earlier - types of arguments to functions: like
(float, int)
for instance - functions can return multiple objects in a tuple
- a tuple with a single value, say 6.5, is noted like this:
(6.5,)
- they come in very handy for exchanges:
left = 'L'
right = 'R'
temp = left
left = right
right = temp
print("left =",left,"and right =",right)
left = 'L'
right = 'R'
(left, right) = (right, left)
print("left =",left,"and right =",right)
left, right = right, left
print("now left =",left,"and right =",right)
some useful functions for lists
.append(x)
, .extend([x])
, .insert(i,x),
.reverse()
, .pop()
, .sort()
, sorted()
odds = [1, 3, 5, 7]
print('odds before:', odds)
odds.append(11)
print('odds after adding a value:', odds)
for R users, the following code does not do what you might think:
odds = [odds, 11]
print('odds=',odds)
odds = [1, 3, 5, 7, 11]
del odds[0]
print('odds after removing the first element:', odds)
odds.reverse()
print('odds after reversing:', odds)
a = odds.pop()
print('odds after popping last element:', odds)
print("this last element was",a)
a = odds.pop(1)
print("popped element number 1 (2nd element):",a)
odds
what +
and *
do to lists (and remember that lists are mutable):
odds = [1, 3, 5, 7]
primes = odds
primes += [2]
print('primes:', primes)
print('odds:', odds)
counts = [2, 4, 6, 8, 10]
repeats = counts * 2
print(sorted(repeats)) # all integers
print(repeats) # unchanged
repeats.sort() # modified in place
print(repeats)
print(sorted([10,2.5,4])) # all numerical
print(sorted(["jan","feb","mar","dec"])) # all strings
print(sorted(["jan",20,1,"dec"])) # error
list comprehension
[xxx for y in z]
where z
is a collection,
y
introduces a local variable name, and xxx
is some
simple function of y
(typically)
counts = [2, 4, 6, 8, 10]
counts + 5 # error
[num+5 for num in counts] # new object
counts
for i in range(0,len(counts)):
counts[i] += 5 # modifies "counts" in place
counts
some useful functions for strings
.strip()
, .split()
, .replace()
, .join()
, .splitlines()
,
taxon = "Drosophila melanogaster"
genus = taxon[0:10]
print("genus:", genus)
gslist = taxon.split(' ')
print(gslist)
print("after splitting at each space: genus=",
gslist[0],", species=",gslist[1], sep="")
print(taxon) # has not changed: immutable
print(taxon.replace(' ','_'))
print(taxon) # has not changed
mystring = "\t hello world\n \n"
mystring
print('here is mystring: "' + mystring + '"')
print('here is mystring.strip(): "' + mystring.strip() + '"')
print('here is mystring.rstrip(): "' + mystring.rstrip() + '"') # right strip (or tRailing) only
" abc\n \n\t ".strip()
join
to concatenate multiple string items from a list
into a single string:
mylist = ["AA","BB","CC"]
"coolseparator".join(mylist)
some useful modules
numpy, time, matplotlib.pyplot, glob, re, sys, argparse
import module
or import module as nickname
or
from module import function1, function2
or
from module import *
some useful functions/methods
type
, print
, range
, list
, del
,
len
, abs
, in
, **
for power,
+
to concatenate strings or lists
to check assumptions: assert test_expression, "error message"