Learning Python: Unit 4, Statements (original) (raw)
4. Basic Statements
Python program structure
♦ Programs are composed of modules
♦ Modules contain statements
♦ Statementscontain expressions: logic
♦ Expressions create and process objects
Statement | Examples |
---|---|
Assignment | curly,moe, larry = 'good', 'bad', 'ugly' |
Calls | stdout.write ("spam, ham, toast\n") |
Print (a call in 3.X) | print 1, "spam", 4, 'u', |
If/elif/else | if "python" in text: mail(poster, spam) |
For/else | for peteSake in spam: print peteSake |
While/else | while 1: print 'spam',i;�i=i+1 |
Pass | while 1: pass |
Break, Continue | while 1: break |
Try/except/finally | try: spam() except: print 'spam error' |
Raise | raiseoverWorked, cause |
Import, From | import chips; from refrigerator import beer |
Def, Return,Yield | def f(a, b, c=1, *d): return a+b+c+d[0] |
Class | class subclass(superclass): staticData = [] |
Global, Nonlocal (3.X) | def function(): global x, y; x = 'new' |
Del | del spam[k]; del spam[i:j]; del spam.attr� |
Exec (a call in 3.X) | exec "import " + moduleName in gdict, ldict |
Assert | assert name != "", "empty name field" |
With/As (2.6+) | with open('text.dat') as F: process(F) |
General syntax concepts
Python syntax
♦ No variable/type declarations
♦ No braces or semicolons
♦ The �what you see is what you get� of languages
Python assignment
♦ Assignments create object references
♦ Names are created when first assigned
♦ Names must be assigned before being referenced
A Tale of Two Ifs�
C++/Java/etc.:
if (x) {
��� x = y + z; �����// braces, semicolons, parens
}
Python:
if x:
��� x = y + z������ # indented blocks, end of line, colon
● What Python removes [(), ;, {}], and adds [:]
● Why indentation syntax? [readability counts!]
Demo: coding read/eval loops
■ while loop → input, process, print
■ Console input: input() in 3.X, raw_input() in 2.X
■ Console output: print(reply) in 3.X, �print reply� in 2.X
■ Adding converters, if/elif/else, try/except/else
Assignment
♦ �=� assigns object references to names or components
♦ Implicit assignments: import, from, def, class, for, calls
spam = 'SPAM' | basic form |
---|---|
spam, ham = 'yum', 'YUM' | tuple assignment |
[spam, ham] = ['yum', 'YUM'] | list assignment |
a, b, c, d = 'spam' | sequence assign |
spam = ham = 'lunch' | multiple-target |
spam += 42; ham *= 12 | Augmented (2.0) |
a, *b, c = [1, 2, 3, 4] | Extended (3.X) |
See also �About the stars�� in functions unit, for �*X� forms that unpack instead of collecting
Variable name rules
♦ (�_� or letter) + (any number of letters, digits, �_�s)
♦ Case matters: �SPAM� is not �spam�
♦ But can�t use reserved words:
■ + �yield�, for generators (2.3 and later)
■ + �with� and �as� for context managers (2.6, optional in 2.5 though not in 2.5 IDLE!)
■ 3.X:minus �print�, �exec�; plus �None�, �True�, �False�, �nonlocal� (and in 3.5+: �async�, �await�)
and��� | assert | break | class |
---|---|---|---|
continue | def | del | elif |
else | except | exec | finally |
for | from | global | if |
import | in | is | lambda |
not | or | pass | |
raise | return | try | while |
♦ Also applies to module file names:
► �my-code.py� can be run, but not imported!
Expressions
♦ Useful for calls, and interactive prints
♦ Expressions can be used as statements
♦ But statements cannot be used as expressions (�=�)
�
Operation | Interpretation |
---|---|
spam(eggs, ham) | function calls |
spam.ham (eggs) | method calls |
spam | interactive print |
spam < ham and ham != eggs | compoundexpr's |
spam < ham < eggs | range tests |
See ahead�
♦ Python 2.0+ �list comprehension� expressions (covered in Functions)
♦ Similar to map/lambda combination (result=[0,1,4,9])
[i**2 for i in range(4)]� _�like�_� map((lamba x: x**2), range(4))
����
♦ �print� statement writes objects to the �stdout� stream
♦ File object �write� methods write strings to files
♦ Adding a trailing comma suppresses line-feed
♦ Reset �sys.stdout� to catch print output
♦ 3.X: a built-in function call with arguments in �()�
Python 2.X form:
Operation | Interpretation |
---|---|
print spam, ham | print objects to sys.stdout |
print spam, ham, | don�t add linefeed at end |
print>>file, spam | Python 2.0: not to stdout |
Python 3.X form:
� print(spam, ham, sep='::', end='.\n', file=open('save.txt', 'w'), flush=True)
Usable in 2.X via:
� from __future__ import print_function
Otherwise, 2.X� →� 3.X mappings:
� print a������� →� print(a)
� print a, b, c� →� print(a, b, c)
� print a, b,��� →� print(a, b, end='')
� print>>F, a��� →� print(a, file=F)
The Python �Hello world� program
● Expression results don�t need to be printed at top-level
>>> print 'hello world'������������ # 3.X: print('text')
helloworld
>>> 'hello world'
'hello world'
● The hard way
>>> x = 'hello world'
>>> import sys
>>> sys.stdout.write(str(x) + '\n')����
● sys.stdout can be assigned
��
>>> sys.stdout= open('log', 'a')�������� # or a class with .write
>>> print x
If selections
♦ Python�s main selection construct
♦ No �switch�: via if/elif/else, dictionaries, or lists
♦ See also expression ahead:� X = B if A else C
General format
if :
���
elif:������������ # optional elif�s
���
else:�������������������� # optional else
���
Examples
>>> if 3 > 2:
...����print 'yep'
...
yep
>>> x = 'killer rabbit'
>>> if x == 'bunny':
...���� print 'hello little bunny'
... elifx == 'bugs':
...���� print "what's up doc?"
... else:
...���� print 'Run away!... Run away!...'
...
Run away!... Run away!...
>>> choice = 'ham'
>>> print {'spam':� 1.25,�������� # dictionary switch
...������� 'ham':��1.99,
...������� 'eggs':�0.99,
...������� 'bacon': 1.10}[choice]
1.99
# with actions
{'spam':� (lambda: �),
�'ham':��(lambda: �),
��}[choice]()
Python syntax rules
♦ Compound statements = header, �:�, indented statements
♦ Block and statement boundaries detected automatically
♦ Comments run from �#� through end of line
♦ Documentation strings at top of file, class, function
Block delimiters
♦ Block boundaries detected by line indentation
♦ Indentation is any combination of spaces and tabs
♦ Tabs = N spaces up to multiple of 8 (but don�t mix)
Statement delimiters
♦ Statement normally end at end-of-line, or ';'
♦ Statements may span lines if open syntactic pair: ( ), { }, [ ]
♦ Statements may span lines if end in backslash (outdated feature)
♦ Some string constants span lines too (triple-quotes)
Special cases
L = ["Good",
���� "Bad",
���� "Ugly"]����������� # open pairs may span lines
x = 1; y = 2; print x�� # more than 1 simple statement
if 1: print 'hello'���� # simple statement on header line
Nesting code blocks
x = 1����������� # block0
if x:
��� y = 2�������# block1
��� if y:
������� print 'block2'
��� print 'block1'
print 'block0'
The documentation sources interlude
Form | Role |
---|---|
# comments | In-file documentation |
The dir function | Lists of attributes available on objects |
Docstrings: __doc__ | In-file documentation attached to objects |
PyDoc: The help function | Interactive help for objects |
PyDoc: HTML reports | Module documentation in a browser |
Standard manual set | Official language and library descriptions |
Web resources | Online tutorial, examples, and so on |
Published books | Commercially-available texts (see Resources) |
>>> import sys
>>> dir(sys)��������������������������������������������� # also works on types, objects, etc.
['__displayhook__', '__doc__', '__excepthook__', '__name__', �
>>> print sys.__doc__
This module provides access to some objects �
>>> help(sys)
Help on built-in module sys: �
PyDoc
● GUI till 3.2:
■ Start/App menu, PythonXX/ModuleDocs
■ Or run Python script pydocgui.pyw in stdlib
■ Or command line �python -m pydoc�g� (or C:\Python3x\python �)
● Browser in 3.2+:
■ Command line �python -m pydoc �b�
■ Or on Windows �py −3 -m pydoc�b�
■ Or on some Python 3.X: Start/App menu, PythonXX/ModuleDocs
# File: docstrings.py
"""
Module documentation
Words Go Here
"""
spam = 40
def square(x):
���"""
���function documentation
��� can we have your liver then?
���"""
��� return x ** 2
class SomeClass:� # see ahead
���"""
��� class docs go here, and can also
��� be in nested method def statements
���"""
��� pass
>>> import docstrings
>>> help(docstrings)
>>> help(docstrings.square)
Truth tests revisited
♦ True = non-zero number, or non-empty object
♦ Comparisons operators return �True� (1) or �False� (0)
♦ Boolean operators �short-circuit� when result known
♦ Boolean operators return an operand object
��
Object | Value |
---|---|
"spam" | true |
"" | false |
[] | false |
{} | false |
1 | true |
0.0 | false |
None | false |
Examples
>>> 2 < 3, 3 < 2������� # return True (1) or False (0)
(True, False)
>>> 2 or 3, 3 or 2����� # return left operand if true
(2, 3)����������������� # else return right operand (T|F)
>>> [] or 3
3
>>> [] or {}
{}
>>> 2 and 3, 3 and 2��� # return left operand if false
(3, 2)����������������� # else return right operand (T|F)
>>> [] and {}
[]
>>> 3 and []
[]
C�s ternary operator in Python
● Prior to 2.5: � X = (A and B) or C
● New in 2.5:���� X = B if A else C
if A:
��� X = B
else:
��� X = C
Boolean type (2.3+)
● bool is a subclass of int
● bool has two instances: True and False
● True,False are 1,0 but print differently
>>> 1 > 0
True
>>> True == 1, True is 1
(True, False)
�
>>> True + 1
2
While loops
♦ Python�s most general iteration construct
♦ One of two looping statements: while, for
♦ Implicit looping tools: map, reduce, filter, in, list (and other) comprehensions
General format
while :
���
else:�������������������� # optional else
��� �������� # run if didn�t exit with break
Examples
>>> while True:
...���� print 'Type Ctrl-C to stop me!'
>>> count = 5
>>> while count:
...���� print count,
...���� count -= 1
...�
5 4 3 2 1
>>> x = 'spam'
>>> while x:
...���� print x,
...���� x = x[1:]�����# strip first char off x
...
spam pam am m
>>> a=0; b=10
>>> while a < b:������ # one way to code counter loops
...���� print a,������ # 3.X: print(a, end='')
...���� a = a+1������� # or:�a += 1
...
0 1 2 3 4 5 6 7 8 9
Break, continue, pass, and the loop else
♦ _break_�������� jumps out of the closest enclosing loop
♦ continue ��� jumps to the top of the closest enclosing loop
♦ _pass_��������� does nothing: an empty statement placeholder
♦ loop _else_��� run if loop exits normally, without a �break�
♦ 3.X� ����� a literal ��� ellipsis can work like a �pass�
General loop format
while :
���
��� if : break�������� # exit loop now, skip else
��� if : continue����� # go to top of loop now
else:
��� ������������ # if we didn�t hit a �break�
Examples
■ Pass: an infinite loop
● Better example: stubbed-out function bodies, �TBD�
whileTrue: pass�� # ctrl-C to stop!
■ Continue: print even numbers
● Avoids statement nesting (but use sparingly!)
x = 10
while x:
��� x = x-1
��� if x % 2 != 0: continue���� # odd?--skip
��� print x,
■ Break: find factors
● Avoids search status flags
x = y / 2
while x > 1:
��� if y % x == 0:���������������� # remainder
������� print y, 'has factor', x
������� break��������������������� # skip else
��� x = x-1
else:����������������������������� # normal exit
��� print y, 'is prime'
��
For loops
♦ A general sequence (iterable) iterator
♦ Works on strings, lists, tuples, other
♦ Replaces most �counter� style loops
♦ Original: repeatedly indexes object until IndexError detected
♦ Newer: repeatedly calls next(iter(object)) until StopIteration
♦ Preview: also works on Python classes and C types
General format
for in :�� # assign object items to target
���
��� if : break������� # exit loop now, skip else
��� if : continue���� # go to top of loop now
else:
��� ����������� # if we didn�t hit a �break�
Examples
>>> for x in ["spam", "eggs", "spam"]:
...���� print x,
...
spam eggs spam
>>> prod = 1
>>> for i in (1, 2, 3, 4): prod *= i������� # tuples
...
>>> prod
24
>>> S = 'spam'
>>> for c in S: print c�������������������� # strings
...
s
p
a
m
Works on any iterable object: files, dicts
��������������
>>> for line in open('data.txt'):
������� print line.upper()������� # calls next(), catches exc
����
>>> for key in D:
�������print key, D[key]
Demo: iteration protocol and files
■ file.__next__()gets next line, like file.readline(), but eof differs
■ Use file.next()in 2.X, or next(file) in either 2.X or 3.X
■ All iteration tools/contexts use the iteration protocol
■ Protocol: I=iter(X), call next(I) * N, catch StopIteration
■ iter(X)optional for single-scan iterables (e.g., files)
■ Any such object works in for loops, comprehensions, �
■ line.rstrip(),line.upper()are string methods
Comprehensions:
● [expr-with-var for var in iterable]
● [expr-with-var for var in iterable if expr-with-var]
● [expr-with-vars for var1 in iterable1 for var2 in iterable2]
● Also works for sets, dictionaries, generators in 2.7+: {}, ()
● Hint: comps have statement equivalents: for/if/append() nesting
● Hint: KISS! � if it�s hard for you read, don�t do it�
Loop coding techniques
♦ _for_subsumes most counter loops
♦ _range_generates a list of integers to iterate over
♦ xrange similar, but doesn�t create a real list
♦ avoid range, and the temptation to count things!
# The easy (and fast) way
>>> X = 'spam'
>>> for item in X: print item, �����������# step through items
...
s p a m
# The hard way: a C-style for loop
>>> i = 0
>>> while i < len(X):�������������������� # manual while indexing
...���� print X[i],; i += 1
...
s p a m
# Range and fixed repitions
>>> range(5), range(2, 5)
([0, 1, 2, 3, 4], [2, 3, 4])
>>> for i in range(4): print 'A shrubbery!'
...
A shrubbery!
A shrubbery!
A shrubbery!
A shrubbery!
# Using range to generate offsets (not items!)
>>> X
'spam'
>>> len(X)
4
>>> range(len(X))
[0, 1, 2, 3]
>>> for i in range(len(X)): print X[i],����� # step through offsets
...
s p a m
# Using range and slicing for non-exhaustive traversals
>>> range(2,10,2)
[2, 4, 6, 8]
>>> S = 'abcdefghijk'
>>> for i in range(0,len(S),2): print S[i],
...
a c e g i k
in recent releases�
>>> for c in S[::2]: print c,������������ # S[::-1] reverses
...
a c e g i k
# Using range and enumerate to change a list in-place
>>> L = [1, 2, 3, 4]
>>> for x in L: x += 10
>>> L
[1, 2, 3, 4]
�
�
>>> for i in range(len(L)): L[i] += 10
>>> L
[11, 12, 13, 14]
����
List comprehensions
����
����
>>> M = [x + 10 for x in L]
>> M
21, 22, 23, 24]
����
>>> lines = [line.rstrip() for line in open('README.txt')]
����
>>> [row[1] for row in matrix]
����
� more in functions section
Demo: list comprehensions and files
■ Unless covered earlier (see above)
Enumerate in 2.3+
��������������
>>> for (i, x) in enumerate(L):
���� L[i] = x * 2
>>> L
[22, 24, 26, 28]
>>> enumerate(L)
<enumerate object at 0x00B48440>
>>> list(enumerate(L))
[(0, 22), (1, 24), (2, 26), (3, 28)]
>>> E = enumerate(L)
>>> E.next()
(0, 22)
>>> E.next()������������# see generators in next section
(1, 24)
# Traversing sequences in parallel with zip
>>> L1 = [1,2,3,4]
>>> L2 = [5,6,7,8]
>>>
>>> zip(L1,L2)
[(1, 5), (2, 6), (3, 7), (4, 8)]
>>>
>>> for (x,y) in zip(L1, L2):
...���� print x, y, '--', x+y
...
1 5 -- 6
2 6 -- 8
3 7 -- 10
4 8 -- 12
# Traversing dictionaries by sorted keys
>>> D = {'a':1, 'b':2, 'c':3}
>>> D
{'a': 1, 'c': 3, 'b': 2}
>>> Ks = D.keys()
>>> Ks.sort()
>>> for k in Ks: print D[k],
1 2 3
Sorted in 2.4+
�
>>> D
{'a': 1, 'c': 3, 'b': 2}
>>> for k in sorted(D): print D[k],
1 2 3
Comprehensive loop examples
Matrix processing, with nested loops + comprehensions
��� See on class CD: Extras\Code\Misc\matrix-code.py
Common ways to read from files
# file creation
>>> myfile = open('myfile.txt', 'w')
>>> for i in range(3):
������� myfile.write(('spam' * (i+1)) + '\n')
>>> myfile.close()
# all at once
�
>>> print open('myfile.txt').read()
spam
spamspam
spamspamspam
# line by line
�
>>> myfile = open('myfile.txt')
>>> while True:
������� line = myfile.readline()
������� if not line: break
������� print line,
spam
spamspam
spamspamspam
# all lines at once
>>> for line in open('myfile.txt').readlines():
������� print line,
����
spam
spamspam
spamspamspam
# file iterators: line by line
>>> for line in open('myfile.txt'):
������� print line,
����
spam
spamspam
spamspamspam
# by byte counts
>>> myfile = open('myfile.txt')
>>> while True:
������� line = myfile.read(10)
������� if not line: break
������� print '[' + line + ']',
[spam
spams] [pam
spamsp] [amspam
]
Summing data file columns
>>> print open('data.txt').read()
001.1 002.2 003.3
010.1 020.2 030.3 040.4
100.1 200.2 300.3
>>> sums = {}
>>> for line in open('data.txt'):
������� cols = [float(col) for col in line.split()]� # next!
������� for pos, val in enumerate(cols):
����������� sums[pos] = sums.get(pos, 0.0) + val
>>> for key in sorted(sums):
������� print key, '=', sums[key]
0 = 111.3
1 = 222.6
2 = 333.9
3 = 40.4
>>> sums
{0: 111.3, 1: 222.59999999999999, 2: 333.90000000000003,
3: 40.399999999999999}
Basic coding gotchas
■ Don�t forget to type a �:� at the end of compound statement headers
■ Be sure to start top-level (unnested) code in column 1
■ Blank lines in compound statements are ignored in files, but end the statement at the interactive prompt
■ Avoid mixing tabs and spaces in indentation, unless you�re sure what your editor does with tabs
■ C programmers: you don�t need �( )� around tests in �if� and �while�; you can�t use �{ }� around blocks
■ In-place change operations like list.append() and list.sort() don�t return a value (really, they return �None�); call them without assigning the result.
■ Add parens to call a function: �file.close()� is a call, �file.close� is a reference only
�
Preview: program unit statements
■ Create and process higher-level program components
Unit | Role |
---|---|
Functions | procedural units |
Modules | code/data packages |
Exceptions | errors and special cases |
Classes | new objects |
C modules | optimization, customization, integration |
��
��
Lab Session 3
Click here to go to lab exercises
Click here to go to exercise solutions