Introduction to Python

Prep Work

  • download anaconda from the link belwo

https://www.anaconda.com/download/#windows

Open it with Anaconda Prompt

create a new environment,克隆一个基础环境

conda create --name hello --clone base
  • download Pycharm
  • create a new project in pycharm using the environment above

Basic Language

1. Reserved Keywords

Although Python will not stop you, do not use these as variable or function names.

and			del			from 		not 		while
as 			elif		global 		or 			with
assert 		else 		if 			pass 		yield
break 		except 		import 		print
class 		exec 		in 			raise
continue 	finally 	is 			return
def 		for 		lambda 		try

or these other

abs all any apply basestring bin bool buffer bytearray bytes callable chr classmethod cmp coerce compile complex delattr dict dir divmod enumerate eval execfile file filter float format frozenset getattr globals hasattr hash hex id input int intern isinstance issubclass iter len list locals long map max min next object oct open ord pow print property range raw_input reduce reload repr reversed round set setattr slice sorted staticmethod str sum super tuple type unichr unicode vars xrange zip

2. Numbers

Python has common‑sense number‑handling capabilities.

>>> 2+2
4
>>> 2+2 # and a comment on the same line as code
4
>>> (50‑5*6)/4
5
>>> 7/3 # Integer division returns the floor:
2
>>> 7/‑3 # ext integer down
‑3
>>> width = 20
>>> height = 5*9
>>> width * height
>>> x = y = z = 0 # Zero x, y and z
>>> x
0
>>> y
0
>>> z
0
>>> 3 * 3.75 / 1.5
7.5
>>> 7.0 / 2 # float numerator
3.5
>>> from __future__ import division # no more default integer division!
>>> 7/2
3.5
>>> 7 // 2 # double slash gives integer division
3

You can also cast among the numeric types in a common‑sense way:

>>> int(1.33333)
1
>>> float(1)
1.0
>>> type(1)
int
>>> type(float(1))
float

3. Complex Numbers

Python has rudimentary support for complex numbers.

>>> 1j * 1J
(‑1+0j)
>>> 1j * complex(0,1)
(‑1+0j)
>>> 3+1j*3
(3+3j)
>>> (3+1j)*3
(9+3j)
>>> (1+2j)/(1+1j)
(1.5+0.5j)
>>> a=1.5+0.5j
>>> a.real # the dot notation gets an attribute
1.5
>>> a.imag
0.5
>>> a=3.0+4.0j
>>> float(a)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: can't convert complex to float; use abs(z)
>>> a.real
3.0
>>> a.imag
4.0
>>> abs(a) # sqrt(a.real**2 + a.imag**2)
5.0
>>> tax = 12.5 / 100
>>> price = 100.50
>>> price * tax
12.5625
>>> price + _
113.0625
>>> round(_, 2)
113.06

4. Strings

String‑handling is very well developed and highly optimized in Python. We just cover the main points here. First, single or double quotes define a string and there is no precedence relationship between sin‑ gle and double quotes.

>>> 'spam eggs'
'spam eggs'
>>> 'doesn\'t'
"doesn't"
>>> "doesn't"
"doesn't"
>>> '"Yes," he said.'
'"Yes," he said.'
>>> "\"Yes,\" he said."
'"Yes," he said.'
>>> '"Isn\'t," she said.'
'"Isn\'t," she said.'

Python strings have C‑style escape characters for newlinews, tabs, etc.

>>> print """Usage: thingy [OPTIONS]
‑h Display this usage message
‑H hostname Hostname to connect to
"""
>>> # the 'r' makes this a 'raw' string
>>> hello = r"This is a rather long string containing\n\ several lines of text much as you w
>>> print hello
This is a rather long string containing\n\ several lines of text much as you would do in C.
>>> # otherwise, you get the newline \n
>>> hello = "This is a rather long string containing\n\ several lines of text much as you wo
>>> print hello
This is a rather long string containing
several lines of text much as you would do in C.
>>> u'this a unicode string µ ±' # the 'u' makes it a unicode string
>>> u'this a unicode string \xb5 \xb1' # using hex‑codes

5. Slicing Strings

Python is a zero‑indexed language (like C). The color : character denotes slicing.

>>> word = 'Help' + 'A'
>>> word
'HelpA'
>>> '<' + word*5 + '>'
'<HelpAHelpAHelpAHelpAHelpA>'
>>> word[4]
'A'
>>> word[0:2]
'He'
>>> word[2:4]
'lp'
>>> word[‑1] # The last character
'A'
>>> word[‑2] # The last‑but‑one character
'p'
>>> word[‑2:] # The last two characters
'pA'
>>> word[:‑2] # Everything except the last two characters
'Hel'
>>> word[0] = 'Q' # strings are IMMUTABLE
Traceback (most recent call last):
...
TypeError: 'str' object does not support item assignment

6. String Operations

Some basic numerical operations work with strings.

>>> 'hey '+'you' # concatenate with plus operator
'hey you'
>>> 'hey '*3 # multiply duplicates strings
'hey hey hey '

Python has a built‑in and very powerful regular expression module for string manipulations.

7. Substitutions

String substitution creates new strings.

>>> x = 'This is a string'
>>> print x.replace('string','newstring')
This is a newstring
>>> print x # x hasn't changed
This is a string

8. Formatting Strings

There are so many ways to format strings in Python, but here is the simplest that follows C‑language sprintf conventions in conjunction with the modulo operator %.

>>> print 'this is a decimal number %d' % ( 10 )
this is a decimal number 10
>>> print 'this is a float %3.2f' % (10.33)
this is a float 10.33
>>> x = 1.03
>>> print 'this is a variable %e' % (x) # exponential format
this is a variable 1.030000e+00

Basic Data Structures

Python provides many powerful data structures. The two most powerful and fundamental are the list and dictionary. We have already seen that strings are immutable. Python also provides immutable data structures.

1. Lists – generalized containers (mutable)

The list is an order‑preserving general container.

>>> mix=[3,'tree',5.678,[8,4,2]]; mix # List creation
[3, 'tree', 5.6779999999999999, [8, 4, 2]]
>>> mix[1] # Indexing individual elements
'tree'
>>> mix[0]
3
>>> mix[‑2] # Indexing from the right
5.6779999999999999
>>> mix[3]
[8, 4, 2]
>>> mix[3][1] # Last element is itself a list
4
>>> mix[0]=666; mix # Mutable
[666, 'tree', 5.6779999999999999, [8, 4, 2]]
>>> submix=mix[0:3]; submix # Creating sublist
[666, 'tree', 5.6779999999999999]
>>> switch=mix[3]+submix; switch # + Operator
[8, 4, 2, 666, 'tree', 5.6779999999999999]
>>> len(switch) # Built‑in Function
6
>>> resize=[6.45,'SOFIA',3,8.2E6,15,14]; len(resize)
6
>>> resize[1:4]=[55]; resize; len(resize) # Shrink a sublist
[6.4500000000000002, 55, 15, 14]
4
>>> resize[3]=['all','for','one']; resize; len(resize)
[6.4500000000000002, 55, 15, ['all', 'for', 'one']]
4
>>> resize[4]=2.87 # Cannot append this way
Traceback (most recent call last):
...
IndexError: list assignment index out of range
>>> temp=resize[:3]
>>> resize=temp+resize[3]; resize; len(resize) # add to list
[6.4500000000000002, 55, 15, 'all', 'for', 'one']
6
>>> del resize[3]; resize; len(resize) # delete an element
[6.4500000000000002, 55, 15, 'for', 'one']
5
>>> del resize[1:3]; resize; len(resize) # delete a sublist
[6.4500000000000002, 'for', 'one']
3
  • # Sorting lists
    >>> sorted([1,9,8,2]) # this sorts lists
    [1, 2, 8, 9]
    

2. Tuples – containers (immutable)

Tuples are another general purpose sequential container in Python, very similar to lists, but these are immutable. Tuples are delimited by commas (parentheses are grouping symbols).

>>> tuple([1,3,4])
(1, 3, 4)
>>> 1,3,4
(1, 3, 4)

>>> pets=('dog','cat','bird') #Parentheses () create tuples
>>> pets[0]
'dog'
>>> pets + pets # addition
('dog', 'cat', 'bird', 'dog', 'cat', 'bird')
>>> pets*3
('dog', 'cat', 'bird', 'dog', 'cat', 'bird', 'dog', 'cat', 'bird')
>>> pets[0]='rat' # assignment not work!
TypeError: 'tuple' object does not support item assignment

3. Key Concept: Mutable vs. Immutable

In Python, the easiest way to think of variables is in terms of immutable (not changeable) or mutable (changeable).

>>> x = [1,3,4,['one',1.33]] # lists are a mutable (i.e. changeable)
>>> x[0]='banana' # no problem changing this
>>> y = (1,3,4,['one',1.33]) # tuples are a immutable (i.e. not changeable)
>>> y[0]='banana'
Traceback (most recent call last):
...
TypeError: 'tuple' object does not support item assignment

    
>>> z=('banana',)+y[1:] # I need to make a new tuple to change it
>>> print id(y)
25690000
>>> print id(z)
26030320
>>> print id(x)
26055664
>>> x[1]='here I go again' # make a change (okay!)
>>> print id(x)
26055664

4. Dictionaries – The MOST IMPORTANT Python data structure

>>> top={'math':'Gauss','phys':'Newton','art':'Vemeer','phil':'Emerson',
... 'play':'Shakespeare','actor':'Kidman','direct':'Kubrick',
... 'author':'Hemmingway','bio':'Watson','group':'R.E.M'}
...
>>> len(top) #{ } are dictionary creation operators
10
>>> top['pres']='F.D.R.'
>>> top['bio']='Darwin'
>>> #can delete a key,value pair
>>> del top['actor']
>>> # another way of creating a dict
>>> x=dict(key='value',another_key=1.333,more_keys=[1,3,4,'one'])
>>> print x
{'another_key': 1.333, 'more_keys': [1, 3, 4, 'one'], 'key': 'value'}
>>> x={(1,3):'value'} # any immutable type can be a valid key
>>> print x
{(1, 3): 'value'}
>>> x[(1,3)]='immutables can be keys'

What if you want to create a union of dictionaries in one‑line?

>>> d1 = {'a':1, 'b':2, 'c':3}
>>> d2 = {'A':1, 'B':2, 'C':3}
>>> dict(d1,**d2) # combo of d1 and d2
{'A': 1, 'B': 2, 'C': 3, 'a': 1, 'b': 2, 'c': 3}

5. Sets

Python provides mathematical sets and corresponding operations with the set() data structure.

>>> print set([1,2,11,1]) # union‑izes elements
set([1, 2, 11])
>>> print set([1,2,3]) & set([2,3,4]) # intersection
set([2, 3])
>>> print set([1,2,3]) and set([2,3,4]) # not work
set([2, 3, 4])
>>> print set([1,2,3]) ^ set([2,3,4]) # exclusive OR
set([1, 4])
>>> print set([1,2,3]) | set([2,3,4]) # OR
set([1, 2, 3, 4])
>>> print set([ [1,2,3],[2,3,4] ]) # no sets of lists (w/o more work)
Traceback (most recent call last):
TypeError: unhashable type: 'list'

Basic Programming

1. Loops and Conditionals

There are two primary looping constructs in Python: the for loop and the while loop. The syntax of the for loop is straightforward:

>>> for i in range(3):
... print i

Note the colon character at the end. This is your hint that the next line should be indented. The for loop iterates over items that provided by the iterator, which is the range(3) list in the above example. Python abstracts the idea of iterable out of the looping construction so that some Python objects are iterable all by themselves and are just waiting for an iteration provider like a for or while loop to get them going.

The while loop has a similar straightforward construct:

>>> i = 0
>>> while i < 10:
... i += 1
...

Again, note that the presence of the colon character hints at indenting the following line. The while loop will continue until the boolean expression (i.e., i<10) evaluates False. Let’s consider booleans and mem‑ bership in Python.

2. Logic and Membership

Python is a truthy language:

Only these are false:

  • None
  • False
  • zero of any numeric type, for example, 0, 0L, 0.0, 0j.
  • any empty sequence, for example, '', (), [].
  • any empty mapping, for example, {}.
  • instances of user‑defined classes, if the class defines a nonzero() or len() method, when that method returns the integer zero or bool value False.
>>> bool(1)
True
>>> bool([]) # empty list
False
>>> bool({}) # empty dictionary
False
>>> bool(0)
False
>>> bool([0,])
True

Python is syntactically clean about numeric intervals!

>>> 3.2 < 10 < 20
True

You can use disjunctions (or), negations (not), and conjunctions (and) also.

>>> 1 < 2 and 2 < 3 or 3 < 1
True
>>> 1 < 2 and not 2 > 3 or 1<3
True

It’s advisable to use grouping parentheses for readability. You can use logic across iterables as in the following:

>>> (1,2,3) < (4,5,6) # at least one True
True
>>> (1,2,3) < (4,5,1) # logical disjunction across elements
True

I’ve never seen this idiom in the wild, though. Don’t use relative comparison for Python strings (i.e., 'a'< 'b'). It gets weird like that. Use string matching operations instead (i.e., ==).

Membership testing uses the in keyword.

>>> 'on' in [22,['one','too','throw']]
False
>>> 'one' in [22,['one','too','throw']] # no recursion
False
>>> 'one' in [22,'one',['too','throw']]
True
>>> ['too','throw'] not in [22,'one',['too','throw']]
False

If you are testing membership across millions of elements it is much faster to use set() instead of list. For example,

>>> 'one' in {'one','two','three'}
>>> 'one' in set(['one','two','three'])

The is keyword is stronger than equality, because it checks if two objects are the same

>>> x = 'this string'
>>> y = 'this string'
>>> print x is y
False
>>> print x==y
True

However, is is really checking the id of each of the items:

>>> x=y='this string'
>>> print id(x),id(y)
4281928416 4281928416
>>> print x is y
True

By virtue of this, the following idioms are common:

x is True, x is None.

3. Conditonals

Now that we understand boolean expressions, we can build conditional statements using if.

>>> if 1 < 2:
... print 'one less than two'

There is an else and elif, but no switch statement.

>>> a = 10
>>> if a < 10:
... print 'a less than 10'
... elif a < 20:
... print 'a less than 20'
... else:
... print 'a otherwise'

There is a one‑liner for conditionals

>>> x = 1 if (1>2) else 3 # 1‑line conditional
>>> print x
3

The for loop can have an else clause as in the following

>>> rangelist = range(10)
>>> print rangelist
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> for number in rangelist:
... # Check if number is one of
... # the numbers in the tuple.
... if number in (3, 4, 7, 9):
... # "Break" terminates a for without
... # executing the "else" clause.
... break
... else:
... # "Continue" starts the next iteration
... # of the loop. It's rather useless here,
... # as it's the last statement of the loop.
... continue
... else:
... # The "else" clause is optional and is
... # executed only if the loop didn't "break".
... pass # Do nothing

This is good for recognizing when a loop exits normally or via break.

4. List Comprehensions

Collecting items over a loop is common that it is its own idiom in Python. That is,

>>> out=[] # initialize container
>>> for i in range(10): out.append(i**2)
>>> out
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

This can be abbreviated as a list comprehension.

>>> [i**2 for i in range(10)] 
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Conditional elements can be embedded in the list comprehension.

>>> [i**2 for i in range(10) if i % 2] # embedded conditional
[1, 9, 25, 49, 81]

These comprehensions also works as dictionaries and sets.

>>> {i:i**2 for i in range(5)}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
>>> {i**2 for i in range(5)}
{0, 1, 4, 9, 16}

5. Functions

There are two common ways to define functions. You can use the def keyword as in the following:

>>> def foo(): return 'I said foo'
>>> foo()
'I said foo'

Note that you need a return statement and that you need the parenthesis to actually invoke the func‑ tion. Without the return statement, the functions returns the None singleton.

Functions are first‑class objects.

>>> foo # just another Python object
<function __main__.foo>

Practically speaking, this means they can be manipulated like any other Python object — they can be put in containers and passed around without any special handling. Naturally, we want to supply arguments to our functions. There are two kinds of function arguments positional and keyword.

>>> def foo(x): # positional unnamed argument
... return x*2
...
>>> foo(10)
20

Keyword arguments allow you to specify defaults.

>>> def foo(x=20): # keyword named argument
... return 2*x
...
>>> foo(1)
2
>>> foo()
40
>>> foo(x=30)
60
>>>
>>> def foo(x=20,y=30):
... return x+y
...
>>> foo(20,)
50
>>> foo(1,1)
2
>>> foo(y=12)
32
>>> help(foo)
Help on function foo in module __main__:
...
foo(x=20, y=30) # provides automatic documentation

Python makes it easy to include documentation for your functions using docstrings. The makes the help function more useful for functions.

>>> def foo(position=20,velocity=30): #using a documentation string docstring
... '''position in m
... velocity in m/s
... '''
... return x+y
>>> help(foo)
Help on function foo in module __main__:
...
foo(position=20, velocity=30)
position in m
velocity in m/s

Thus, by using meaningful argument and function names and including basic documentation in the docstrings, you can greatly improve the usability of your Python functions. Also, it is recommended to make function names verb‑like (e.g., get_this, compute_field ) In addition to using the def statement, you can also create functions using lambda. These are sometimes called anonymous functions.

>>> f = lambda x: x**2 # anonymous functions
>>> f(10)
100
>>> [lambda x: x, lambda x:x**2] # list of functions
[<function <lambda> at ...>, <function <lambda> at ...>]
>>> for i in _:
... print i(10)
10
100

So far, we have not made good use of tuple, but these data structures become very powerful when used with functions. This is because they allow you to separate the function arguments (i.e., function signa‑ ture) from the function itself. This means you can pass them around and build function arguments and then later execute them with one or more functions.

The usefulness of tuples derives from using them with functions
>>> args = (1,3,4)
>>> def foo(x,y,z): #defining
... return x+y+z
>>> print foo(*args) # note the asterisk notation
8
This also works with keyword arguments
>>> def foo(x=1,y=2,z=3):
... return x+y+z
>>> kwargs = {'x':10,'y':20,'z':30}
>>> print foo(**kwargs) # note the double asterisks
60
>>> kwargs = {'x':10,'y':20,'z':30,'h':100} # extra argument
>>> print foo(**kwargs) # note the double asterisks
Traceback (most recent call last):
...
TypeError: foo() got an unexpected keyword argument 'h'
This also works in combination
>>> def foo(x,y=2,z=3): # note the the first argument is positional
... return x+y+z
>>> kwargs = {'y':20,'z':30}
>>> args = (1,)
>>> foo(*args,**kwargs)
51

6. Function Variable Scoping

Variables within functions or subfunctions are local to that respective scope. Global variables require special handling if they are going to be changed inside the function body.

>>> x=10 # outside function
>>> def foo():
... return x
>>> def foo():
... x=1 # defined inside function
... return x
>>> def foo():
... global x # define as global
... x=20 # assign inside function scope
... return x
>>> print x
10

7. Function keyword filtering

Using **kwds at the end allows functions to disregard keywords they don’t use while filtering out (using the function signature) the keyword inputs that it does use.

def foo(x=1,y=2,z=3,**kwds):
return x+y+z
def goo(x=10,**kwds):
return foo(x=2*x,**kwds)
def moo(y=1,z=1,**kwds):
return goo(x=z+y,z=z+1,q=10,**kwds)

This means I can call any of these with an unsupported keyword as in

moo(y=91,z=11,zeta_variable = 10,**kwds)

and the zeta_variable will be passed through unused because nobody in the calling sequence uses it. Thus, you can inject some other function in the calling sequence that does use this variable, without having to change the call signatures of any of the other functions. Using keyword arguments this way is very common when using Python to wrap other codes. Here’s another example where we can trace how each of the function signatures are satisfied and the rest of the keyword arguments are passed through.

def foo(x=1,y=2,**kwds):
print 'foo: x = %d, y = %d, kwds=%r'%(x,y,kwds)
print '\t',
goo(x=x,**kwds)
def goo(x=10,**kwds):
print 'goo: x = %d, kwds=%r'%(x,kwds)
print '\t\t',
moo(x=x,**kwds)
def moo(z=20,**kwds):
print 'moo: z=%d, kwds=%r'%(z,kwds)

Then, calling the foo function as shown below:

foo(x=1,y=2,z=3,k=20)

Gives the following output:

foo: x = 1, y = 2, kwds={'k': 20, 'z': 3}
	goo: x = 1, kwds={'k': 20, 'z': 3}
		moo: z=3, kwds={'x': 1, 'k': 20}

Notice how the function signatures of each of the functions are satisfied and the rest of the keyword ar‑ guments are passed through.

8. Functional Programming Idioms

Although not a real functional programming language (i.e., Haskell), Python has useful functional id‑ ioms. These become important in parallel computing frameworks like PySpark, but have become depre‑ cated in Python 3.x.

>>> print map( lambda x: x**2 , range(10))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> [i**2 for i in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> reduce(lambda x,y:x+2*y,[0,1,2,3],0)
12
>>> filter(lambda x: x%2, range(10) )
[1, 3, 5, 7, 9]
>>> [i for i in range(10) if i %2 ]
[1, 3, 5, 7, 9]

Pay attention to the recursive problem that reduce solves because reduce is super‑fast in Python. I’ve seen very tricky problems solved using reduce creatively. For example, the least common multiple algo‑ rithm can be effectively implemented using reduce, as shown:

def gcd(a, b):
"""Return greatest common divisor using Euclid's Algorithm."""
while b:
a, b = b, a % b
return a
def lcm(a, b):
"""Return lowest common multiple."""
return a * b // gcd(a, b)
def lcmm(*args):
"""Return lcm of args."""
return reduce(lcm, args)

File Input/Output

It’s straightforward to read and write files using Python. The same pattern applies when writing to other objects, like sockets.

1. Basic file usage

The following is the traditional way to get I/O in Python. The modern way is to use (The with statement).

2. Serialization: Saving Complex objects

Serialization means packing Python objects to be shipped between separate Python processes or sepa‑ rate computers, say, through a network socket, for example. The multiplatform nature of Python means that one cannot be assured that the low‑level attributes of Python objects (say, between platform types or Python versions) will remain consistent.

For the vast majority of situations, the following will work.

>>> import cPickle
>>> mylist = ["This", "is", 4, 13327]
>>> f=open ('myfile.dat','wb') # write‑binary mode
>>> cPickle.dump(mylist, f)
>>> f.close()
>>> f=open ('myfile.dat','rb') # write‑binary mode
>>> print cPickle.load(f)
['This', 'is', 4, 13327]

3. Pickling a Function

The internal state of a function and how it’s hooked into the Python process in which it was created makes it tricky to pickle functions. As with everything in Python, there are ways around this, depending on your use‑case. The following links provide some context:

Dealing with Errors

This is where Python really shines. More modern languages should adopt the Python approach to error handling. The Python approach is to ask for forgiveness rather than permission. This is the basic template.

>>> try:
... # try something
... except:
... # fix something

The above except block with capture and process any kind of exception that is thrown in the try block. Python provides a long list of built‑in exceptions that you can catch and the ability to create your own exceptions, if needed. In addition to catching exceptions, you can raise your own exception using the raise statement. There is also an assert statement that can throw exceptions if certain statements are not True upon assertion (more on this later).

The following are some examples of how to use the exception handling powers of Python.

>>> def some_function():
... try:
... # Division by zero raises an exception
... 10 / 0
... except ZeroDivisionError:
... print "Oops, invalid."
... else:
... # Exception didn't occur, we're good.
... pass
... finally:
... # This is executed after the code block is run
... # and all exceptions have been handled, even
... # if a new exception is raised while handling.
... print "We're done with that."
>>> some_function()
Oops, invalid.
We're done with that.
>>> out = range (3)
>>> try:
... 10 / 0
... except ZeroDivisionError:
... print 'I caught an attempt to divide by zero'
I caught an attempt to divide by zero
>>> try:
... out[999] # raise IndexError
... except ZeroDivisionError:
... print 'I caught an attempt to divide by zero'
Traceback (most recent call last):
...
IndexError: list index out of range
>>> try:
... 1/0 # raise ZeroDivisionError
... out[999]
... except ZeroDivisionError:
... print 'I caught an attempt to divide by zero but I did not try out[999]'
I caught an attempt to divide by zero but I did not try out[999]
>>> try:
... 1/0 # raise ZeroDivisionError
... out[999]
... except IndexError:
... print 'I caught an attempt to index something out of range'
Traceback (most recent call last):
...
ZeroDivisionError: integer division or modulo by zero
>>> try: #nested exceptions
... try: # inner scope
... 1/0
... except IndexError:
... print 'caught index error inside'
... except ZeroDivisionError as e:
... print 'I caught an attempt to divide by zero inside somewhere'
I caught an attempt to divide by zero inside somewhere
>>> try: #nested exceptions with finally clause
... try:
... 1/0
... except IndexError:
... print 'caught index error inside'
... finally:
... print "I am working in inner scope"
... except ZeroDivisionError as e:
... print 'I caught an attempt to divide by zero inside somewhere'
I am working in inner scope
I caught an attempt to divide by zero inside somewhere
>>> try:
... 1/0
... except (IndexError,ZeroDivisionError) as e:
... if isinstance(e,ZeroDivisionError):
... print 'I caught an attempt to divide by zero inside somewhere'
... elif isinstance(e,IndexError):
... print 'I caught an attempt to index something out of range'
I caught an attempt to divide by zero inside somewhere
>>> try: # more detailed arbitrary exception catching
... 1/0
... except Exception as e:
... print type(e)
<type 'exceptions.ZeroDivisionError'>

Power Python Features to Master

1. The under‑appreciated zip function

Python has a built‑in zip function that can combine iterables pair‑wise.

>>> zip(range(3),'abc')
[(0, 'a'), (1, 'b'), (2, 'c')]
>>> zip(range(3),'abc',range(1,4))
[(0, 'a', 1), (1, 'b', 2), (2, 'c', 3)]

The slick part is reversing this operation using the * operation,

>>> x = zip(range(3),'abc')
>>> print x
[(0, 'a'), (1, 'b'), (2, 'c')]
>>> i,j = zip(*x)
>>> print i
(0, 1, 2)
>>> print j
('a', 'b', 'c')

When combined with dict, zip provide a powerful way to build Python dictionaries,

>>> k = range(10)
>>> v = range(10,20)
>>> dict(zip(k,v))
{0: 10, 1: 11, 2: 12, 3: 13, 4: 14, 5: 15, 6: 16, 7: 17, 8: 18, 9: 19}

2. The max function

The max function takes the maximum of a sequence.

>>> max([1,3,4])
4

If the items in the sequence are tuples, then the first item in the tuple is used for the ranking

>>> max([(1,2),(3,4)])
(3,4)

This function takes a key argument that controls how the items in the sequence are evaluated. For ex‑ ample, we can rank based on the second element in the tuple,

>>> max([(1,4),(3,2)],key=lambda i:i[1])
(1,4)

3. The with statement

Set up a context for subsequent code

class ControlledExecution:
	def __enter__(self):
		#set things up
		return thing
	def __exit__(self, type, value, traceback):
		#tear things down
        
with ControlledExecution() as thing:
	some code

Advanced Language Features

1. Advanced String Formatting

2. Generators

3. Decorators

4. Coroutines

5. Iteration and Iterables

Q.E.D.


To baldly -_- go no man has gone before