Python Learning

Foreword

What

Learning Python by myself.

Here’s some environment configuration:
Version: Python 3.6.3
Platform: macOS 10.12.6
Interpreter: terminal
Text editor: Sublime Text 3
Notebook: Jupyter Notebook

Why

  • Self interest
  • Courses Prerequisites: CS229, Deep Learning, etc
  • (Perhaps next semester I have the chance to teach freshman something about Python:D)

How

Material:

These materials should be enough. What I use is the official tutorial to get an detailed understanding of Python and Python’s most noteworthy features, and get a good idea of the language’s flavor and style.

When

I plan to get the hang of Python in my winter vacation.
Try to get more familiar with Python with practical applications.

Basics

Interactive Mode & Executable mode

When commands are read from a tty, the interpreter is said to be in interactive mode. To start interactive mode, type Python3 in terminal(the default Python version of macOS is Python2, so type Python would start Python2). To stop interactive mode, type exit() to quit.

If code is saved as file with .py, then type Python3 filename.py in terminal to compile and run the file.

On BSD’ish Unix systems, Python scripts can be made directly executable, like shell scripts, by putting the line #!/usr/bin/env python3.
The script can be given an executable mode, or permission, using the chmod +x script.py command.
On Windows systems, there is no notion of an “executable mode”. The Python installer automatically associates .py files with python.exe so that a double-click on a Python file will run it as a script. The extension can also be pyw, in that case, the console window that normally appears is suppressed.

Comment & Prompt

Comment
Comments in Python start with the hash character, #, and extend to the end of the physical line.
The # sign will only comment out a single line, if it’s necessary to add multi-line comments, just begin with # each line. (For multi-line comments, include the whole block in a set of triple quotation marks is okay in .py file, but not interactive mode.)

1
2
# This is a comment.
# Here's another

Prompt
When commands are read from a tty, the interpreter is said to be in interactive mode. In this mode it prompts for the next command with the primary prompt, usually three greater-than signs (>>>); for continuation lines it prompts with the secondary prompt, by default three dots (...).
Generally the prompts are primary prompt. Secondary prompts are used in control flow like if, while, etc.
Primary prompt (after python3 command in my terminal):

1
2
3
4
5
$ python3
Python 3.6.3 (default, Oct 28 2017, 21:24:10)
[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>

Secondary prompt (example from tutorial):

1
2
3
4
5
>>> the_world_is_flat = True
>>> if the_world_is_flat:
... print("Be careful not to fall off!")
...
Be careful not to fall off!

Input and Output

Well, this part is not introduced in tutorial, but when dealing with online practice(like CodeStepByStep), it’s necessary to know how to input and output. So I’d include some information here.

Input:

1
It's advisable to add some prompts when asking for input, so we can add string parameters when calling `input` function. ```x = input("prompts")

The default type of x is string. If we input an integer and what to use x as an integer, use type conversion with int(). x = int(input("prompts"))

Output:
Just like MATLAB, we can output a variable’s value by typing the variable’s name, or use the print() function.
When concatenating strings in print(), we can use both , and +. When using ,, we don’t need to convert int/float to string, and every , is treated as a blank space; while we need to convert int/float to string using str() when using +, but + won’t add extra blank space.
printf-style

format

1
2
>>> print('We are the {} who say "{}!"'.format('knights', 'Ni'))
We are the knights who say "Ni!"

The brackets and characters within them (called format fields) are replaced with the objects passed into the str.format() method.

Positional arguments
A number in the brackets can be used to refer to the position of the object passed into the str.format() method.

1
2
3
4
>>> print('{0} and {1}'.format('spam', 'eggs'))
spam and eggs
>>> print('{1} and {0}'.format('spam', 'eggs'))
eggs and spam

Keyword arguments
If keyword arguments are used in the str.format() method, their values are referred to by using the name of the argument.

1
2
3
>>> print('This {food} is {adjective}.'.format(
... food='spam', adjective='absolutely horrible'))
This spam is absolutely horrible.

Positional and keyword arguments can be arbitrarily combined.

Old string formatting
The % operator can also be used for string formatting.

1
2
3
>>> import math
>>> print('The value of PI is approximately %5.3f.' % math.pi)
The value of PI is approximately 3.142.

printf-style String Formatting

Coding Style

PEP 8 - Style Guide for Python Code

  • Use 4-space indentation, and no tabs.
  • Wrap lines so that they don’t exceed 79 characters.
  • Use blank lines to separate functions and classes, and larger blocks of code inside functions.
  • When possible, put comments on a line of their own.
  • Use docstrings.
  • Use spaces around operators and after commas, but not directly inside bracketing constructs: a = f(1, 2) + g(3, 4)
  • Name your classes and functions consistently; the convention is to CamelCase for classes and lower_case_with_underscores for functions and methods. Always use self as the name for the first method argument.
  • Don’t use fancy encodings if your code is meant to be used in international environments. Python’s default, UTF-8, or even plain ASCII work best in any case.
  • Likewise, don’t use non-ASCII characters in identifiers if there is only the slightest chance people speaking a different language will read or maintain the code.

Number

Python interpreter can act as a simple calculator. So just type math expressions will get the calculation result.

Data type
int
float

Decimal
Fraction

Complex numbers: use j or J suffix to indicate the imaginary part(e.g. 3+5j).

Operation
+: Addition. 2 + 2 = 4
-: Subtract. 3 - 1 = 2
*: Multiply. 2 * 2 = 4
**: Power. 2 ** 7 = 128
/: Division. Always returns a float. 10 / 3 = 3.3333333333333335
//: Floor division. Discard any fractional result and get an integer result.

_: Last printed expression(easier to continue calculations).

Conditions

Comparison
< less than, > greater than, == equal to, <= less than or equal to, >= greater than, != not equal to
in and not in check whether a value occurs (does not occur) in a sequence.
is and is not compare whether two objects are really the same object; this only matters for mutable objects like lists.

Boolean
and, or, not
True, False.
Any non-zero integer value is true; zero is false. The condition may also be any sequence(string, list, etc): anything with a non-zero length is true, empty sequences are false.
short-circuit.

Strings

Strings in Python can be enclosed in both single quotes and double quotes.

Escape character
Just like C, \ can be used to escape quotes in Python as well. \t,\n,etc.

Use raw strings by adding an r before the first quote can prevent \ from being treated as special characters. Often used in regular expressions.(See notes about regular expressions here)

1
2
>>> print(r'C:\some\name')
C:\some\name

Concatenating
Strings can be concatenated with + operator, and repeated with *.
For string literals(i.e. the ones enclosed between quotes) next to each other are automatically concatenated.
Remember to use str() when concatenating strings and other data types(e.g. int).
s.join() can combine the words of the text into a string using s as the glue.

Index
Indices of strings can be non-negative(just like C array) and negative(start counting from the right).

1
2
3
4
5
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5 6
-6 -5 -4 -3 -2 -1

Slicing
Like MATLAB, Python supports slicing(word[0:2]), which allows to obtain substring.
Note the start is always included, and the end always excluded.
Default: an omitted first index defaults to zero, an omitted second index defaults to the size of the string being sliced.

Attempting to use an index that is too large will result in an error. However, out of range slice indexes are handled gracefully when used for slicing.

Substring
We test if a string contains a particular substring using the in operator.
We can also find the position of a substring with a string, using find().
s.find(t): index of first instance of string t inside s (-1 if not found)
s.rfind(t): index of last instance of string t inside s (-1 if not found)
s.index(t): like s.find(t) except it raises ValueError if not found
s.rindex(t): like s.rfind(t) except it raises ValueError if not found

Immutable
Python strings are immutable, just as in Java. Thus, if it’s necessary to edit a string, just create a new one.

Multi-lines
This is introduced in NLTK’book Chapter 3
Sometimes strings go over several lines. Python provides us with various ways of entering them. In the next example, a sequence of two strings is joined into a single string. We need to use backslash or parentheses so that the interpreter knows that the statement is not complete after the first line.

1
2
3
4
5
6
7
8
9
ex1 = "This is example using "\
"backslash"
ex2 = ("This is example using"
"parentheses.")
# the above methods won't add newline '\n' to the string
ex3 = '''hello
world'''
# Using triple-quoted string helps to add newline to the string

Others
The built-in function len() returns the length of a string.
String Methods

s.startswith(t): test if s starts with t
s.endswith(t): test if s ends with t
t in s: test if t is a substring of s
s.islower(): test if s contains cased characters and all are lowercase
s.isupper(): test if s contains cased characters and all are uppercase
s.isalpha(): test if s is non-empty and all characters in s are alphabetic
s.isalnum(): test if s is non-empty and all characters in s are alphanumeric
s.isdigit(): test if s is non-empty and all characters in s are digits
s.istitle(): test if s contains cased characters and is titlecased (i.e. all words in s have initial capitals)

title(): convert the first character in each word to uppercase and remaining characters to lowercase in string and returns new string
upper(): convert all characters to uppercase
lower(): convert all characters to lowercase

rstrip(): returns a copy of the string with trailing characters removed.
lstrip(): returns a copy of the string with leading characters removed.
strip(): returns a copy of the string with the leading and trailing characters removed.

replace(t, u): replace instances of t with u.

Control Flow

if Statement

1
2
3
4
5
6
if ... :
...
elif ... :
...
else:
...

There can be zero or more elif parts, and the else part is optional.
Note there’s no switch case in Python.

for Statement
Python’s for statement iterates over the items of any sequence(a list or a string), in the order that they appear in the sequence.

1
2
3
4
5
6
7
8
>>> # Measure some strings:
... words = ['cat', 'window', 'defenestrate']
>>> for w in words:
... print(w, len(w))
...
cat 3
window 6
defenestrate 12

The range() Function
for i in range(5)
range() function may contain 1, 2 or 3 parameters.
range(term): Generate term values from 0 to (term - 1). Note that term should be positive integers or it will return an empty list.
range(begin, end): Generate values from begin to (end - 1).
range(begin, end, step): Specify a different increment(step), which can even be negative.

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.

break and continue Statements, and else Clauses on Loops

The break statement breaks out of the innermost enclosing for or while loop.
The continue statement continues with the next iteration of the loop.
These two statements are borrowed from C.

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> 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

pass Statements
The pass statement does nothing. It can be used when a statement is required syntactically but the program requires no action.

1
2
3
>>> while True:
... pass # Busy-wait for keyboard interrupt (⌃+C)
...

This is commonly used for creating minimal classes:

1
2
3
>>> class MyEmptyClass:
... pass
...

pass can be used 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.

1
2
3
>>> def initlog(*args):
... pass # Remember to implement this!
...

Functions

Detail
The keyword def introduces a function definition. It must be followed by the function name and the parenthesized list of formal parameters. The statements that form the body of the function start at the next line, and must be indented.

docstring
The first statement of the function body can optionally be a string literal(in three single quotes ''' '''); this string literal is the function’s documentation string, or docstring. This line should begin with a capital letter and end with a period.
Docstrings can include a doctest block, illustrating the use of the function and the expected output. These can be tested automatically using Python’s docutils module. Docstrings should document the type of each parameter to the function, and the return type. At a minimum, that can be done in plain text.

call by value
The actual parameters (arguments) to a function call are introduced in the local symbol table of the called function when it is called; thus, arguments are passed using call by value (where the value is always an object reference, not the value of the object). When a function calls another function, a new local symbol table is created for that call.
Actually, call by object reference would be a better description, since if a mutable object is passed, the caller will see any changes the callee makes to it (items inserted into a list).

return
The return statement returns with a value from a function. return without an expression argument returns None. Falling off the end of a function also returns None.

default argument values
When defining functions, it’s useful to specify a default value for one or more arguments. This creates a function that can be called with fewer arguments than it is defined to allow.
Remember that the default value is evaluated only once.

keyword argument & positional argument
From Glossary
A value passed to a function(or method) when calling the function. There are two kinds of argument:
· keyword argument. an argument preceded by an identifier(e.g. name=) in a function call or passed as a value in a dictionary preceded by **.
· positional argument. an argument that is not a keyword argument. Positional arguments can appear at the beginning of an argument list and/or be passed as elements of an iterable preceded by *.

When a final formal parameter of the form **name is present, it receives a dictionary containing all keyword arguments except for those corresponding to a formal parameter. This may be combined with a formal parameter of the form *name (described in the next subsection) which receives a tuple containing the positional arguments beyond the formal parameter list. (*name must occur before **name.)

Data Structures

Sequence Types - list, tuple, range
Set Types - set, frozenset
Mapping Types - dict

Lists

List can be written as a list of comma-separated values (items) between square brackets. (similar to Java’s ArrayList)
Lists might contain items of different types, but usually the items all have the same type. squares = [1, 4, 9, 16, 25]
It’s a good choice to name the list variable with plurals.
Index and slicing are similar to those of String.

Mutable
Lists are a mutable type, i.e. it is possible to change their content. Just use the index to change the content(like array in C).

Concatenation
+ operator: squares + [36, 49]
append method: squares.append(64)

Insert
Use insert() to add elements in the specified location.
Use append() to add elements to the end of the list.

Delete
Use del if the index of element is known. del a[0]

Methods of list objects
list.append(x)
Add an item to the end of the list. Equivalent to a[len(a):] = [x].

list.extend(iterable)
Extend the list by appending all the items from the iterable. Equivalent to a[len(a):] = iterable.

list.insert(i,x)
Insert an item at a given position. The first argument is the index of the element before which to insert, so a.insert(0, x) inserts at the front of the list, and a.insert(len(a), x) is equivalent to a.append(x)

list.remove(x)
Remove the first item from the list whose value is x. It is an error if there is no such item.

list.pop([i])
Remove the item at the given position in the list, and return it. If no index is specified, a.pop() removes and returns the last item in the list.

list.index(x[, start[, end]])
Return zero-based index in the list of the first item whose value is x. Raises a ValueError if there is no such item.
The optional arguments start and end are interpreted as in the slice notation and are used to limit the search to a particular subsequence of the list. The returned index is computed relative to the beginning of the full sequence rather than the start argument.

list.count(x)
Return the number of times x appears in the list.

list.sort()
Sort the items of the list in place.

list.reverse()
Reverse the elements of the list in place.

list.copy()
Return a shallow copy of the list. Equivalent to a[:].

List Comprehensions
List comprehensions provide a concise way to create lists.
A list comprehension consists of brackets containing an expression followed by a for clause, then zero or more for of if clauses. The result will be a new list resulting from evaluating the expression in the context of the for and if clauses which follow it.
E.g:

1
2
3
4
5
6
>>> squares = []
>>> for x in range(10):
... squares.append(x**2)
...
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

It is equivalent to squares = [x**2 for x in range(10)]

Various ways to iterate over sequences:

1
2
3
4
5
for item in s # iterate over the items of s
for item in sorted(s) # iterate over the items of s in order
for item in set(s) # iterate over unique elements of s
for item in reversed(s) # iterate over elements of s in reverse
for item in set(s).difference(t) # iterate over elements of s not in t

Given a sequence s, enumerate(s) returns pairs consisting of an index and the item at that index.

sort
Python list have a built-in list.sort() method that modifies the list in-place. There is also a sorted() built-in function that builds a new sorted list from an iterable.
sorted() function returns a new sorted list. list.sort() modifies the list in-place (and returns None to avoid confusion). Usually it’s less convenient than sorted() - but if you don’t need the original list, it’s slightly more efficient.

Both list.sort() and sorted() have a key parameter to specify a function to be called on each list element prior to making comparisons. A common pattern is to sort complex objects using some of the object’s indices as keys. The same technique works for objects with name attributes.
The key-function patterns are very common, and Python provides convenience functions to make accessor functions easier and faster. The operator module has itemgetter(), attrgetter() and a methodcaller() function.

Both list.sort() and sorted() accept a reverse parameter with a boolean value. This is used to flag descending sorts.

Sorts are guaranteed to be stable.
Sorting HOWTO

Tuples

A tuple consists of a number of values separated by commas, and typically enclosed using parentheses.
Tuples are constructed using the comma operator. Parentheses are a more general feature of Python syntax, designed for grouping. A tuple containing a single element is defined by adding a trailing comma. The empty tuple is a special case, and is designed using empty parentheses().

Comparison with list

Type tuple list
Immutable immutable mutable
Element heterogeneous homogeneous
Access unpacking/indexing iterating

Packing and Unpacking
Packing
t = 12345, 54321, 'hello!' is an example of tuple packing

Unpacking
x, y, z = t is called sequence unpacking and works for any sequence on the right-hand side. Sequence unpacking requires that there are as many variables on the left side of the equals sign as there are elements in the sequence. Note that multiple assignment is really just a combination of tuple packing and sequence unpacking.

zip() takes the items of two or more sequences and “zips” them together into a single list of tuples.
Introduction in documentation:

Make an iterator that aggregates elements from each of the iterables.
Returns an iterator of tuples, where the i-th tuple contains the i-th element from each of the argument sequences or iterables. The iterator stops when the shortest input iterable is exhausted.

Therefore, if two (or more) items have diffrent lengths, the length of the tuple is only the shortest. The trailing will be discarded. (If those values are important, use itertools.zip_longest() instead.)

Sets

A set is an unordered collection with no duplicate elements.
Curly braces {} or the set() function can be used to create sets.
set() can be used to remove duplicated items in the list.

Dictionaries

Dictionaries are index by keys, which can be any immutable type; strings and numbers can always be keys. Tuples can be used as keys if they contain only strings, numbers, or tuples; if a tuple contains any mutable object either directly or indirectly, it cannot be used as a key. Since lists are mutable, lists can’t be used as keys as well.

The dictionary methods keys(), values() and items() allow us to access the keys, values, and key-value pairs. (The type is dict_keys, etc. Sometimes we have to convert to list before further processing).

Python’s Dictionary Methods: A summary of commonly-used methods and idioms involving dictionaries.
d = {}: create an empty dictionary and assign it to d
d[key] = value: assign a value to a given dictionary key
d.keys(): the list of keys of the dictionary
list(d): the list of keys of the dictionary
sorted(d): the keys of the dictionary, sorted
key in d: test whether a particular key is in the dictionary
for key in d: iterate over the keys of the dictionary
d.values(): the list of values in the dictionary
dict([(k1,v1), (k2,v2), ...]): create a dictionary from a list of key-value pairs
d1.update(d2): add all items from d2 to d1
defaultdict(int): a dictionary whose default value is zero

Default dictionary
If we try to access a key that is not in a dictionary, we get an error. However, it’s often useful if a dictionary can automatically create an entry for this new key and give it a default value, such as zero or the empty list. For this reason, a special kind of dictionary called a defaultdict is available. In order to use it, we have to supply a parameter which can be used to create the default value, e.g. int, float, str, list, dict, tuple.
If the parameter is None, it’s just just like the original dict. And We can specify any default value we like using lambda expression.

Some advanced data structures

Deque

1
2
from collections import deque
deque([iterable[, maxlen]])

Deques are a generalization of stacks and queues. Deques support thread-safe, memory efficient appends and pops from either side of the deque with approximately the sam O(1) performance in either direction.
The constructor returns a new deque object initialized left-to-right with data from iterable.
If iterable is not specified, the new deque is empty.
If maxlen is not specified or is None, deques may grow to an arbitrary length. Otherwise, the deque is bounded to the specified maximum length. Once a bounded length deque is full, when new items are added, a corresponding number of items are discarded from the opposite end. (Can be used for keeping last N items)

Methods: append(), appendleft(), pop(), popleft(), etc.

Heapq

1
import heapq

The module provides an implementation of the heap queue algorithm. The implementation uses arrays for which heap[k] <= heap[2*k+1] and heap[k] <= heap[2*k+2] for all k, counting elements from zero.
Python implementation uses zero-based indexing. This makes the relationship between the index for a node and the indices for its children slightly less obvious. And the pop method returns the smallest item.

Functions:
heapq.heappush(heap, item), heapq.heappop(heap), heapq.heapify(x), heapq.nlargest(n, iterable, key=None), heapq.nsmallest(n, iterable, key=None).
The latter two functions perform best for smaller values of n. For larger values, it is more efficient to use the sorted() function (with slicing). Also, when n==1, it is more efficient to use the built-in min() and max() functions.

Modules

A module is a file containing Python definitions and statements. The file name is the module name with the suffix .py appended. Definitions from a module can be imported into other modules or into the main module (the collection of variables that you have access to in a script executed at the top level and in calculator mode). Within a module, the module’s name (as a string) is available as the value of the global variable __name__.

Files

open

open(filename, mode)
open() returns a file object. The first argument is a string containing the filename. The second argument is another string containing a few characters describing the way in which the file will be used. mode can be 'r' when the file will only be read, 'w' for only writing (an existing file with the same name will be erased), and 'a' opens the file for appending; any data written to the file is automatically added to the end. 'r+' opens the file for both reading and writing. The mode argument is optional; 'r' will be assumed if it’s omitted.

It is good practice to use the with keyword when dealing with file objects. (similar to with tf.Session() as sess: in TensorFlow). The advantage is that the file is properly closed after its suite finishes, even if an exception is raised at some point. Using with is also much shorter than writing equivalent try-finally blocks:

1
2
>>> with open('workfile') as f:
... read_data = f.read()

If not using with keyword, just call f.close() to close the file and immediately free up any system resources used by it.

read & write

f.read(size)
Reads some quantity of data and returns it as a string (in text mode) or bytes object(in binary mode). size is an optional numeric argument. When size is omitted or negative, the entire contents of the file will be read and returned. Otherwise, at most size bytes are read and returned. If the end of the file has been reached, f.read() will return an empty string('').

f.readline()
Reads a single line from the file; a newline character(\n) is left at the end of the string, and is only omitted on the last line of the file if the file doesn’t end in a newline. This makes the return value unambiguous: if f.readline() returns an empty string, the end of the file has been reached, while a blank line is represented by '\n', a string containing only a single newline.

Looping over the file object:

1
2
>>> for line in f:
... print(line, end='')

Read all the lines of a file in a list: list(f) or f.readlines().

f.write(string) writes the contents of string to the file, returning the number of characters written. Other types of objects need to be converted - either to a string (in text mode) or a bytes object (in binary mode) - before writing them.

Exceptions

Errors detected during execution are called exceptions.
Exceptions come in different types, and the type is printed as part of the message. The string printed as the exception type is the name of the built-in exception that occurred.(true for all built-in exceptions, but need not be true for user-defined exceptions)

All built-in exceptions are listed here

Handling Exceptions

The try statement works as follows.

  • First, the try clause is executed.
  • If no exceptions occurs, the except clause is skipped and execution of the try statement is finished.
  • If an exception occurs during execution of the try clause, the rest of the clause is skipped. Then if its type matches the exception named after the except keyword, the except clause is executed, and then execution continues after the try statement.
  • If an exception occurs which does not match the exception named in the except clause, it is passed on to outer try statements; if no handlers is found, it is an unhandled exception and execution stops with a message.

A try statement may have more than one except clause, to specify handlers for different exceptions. At most one handler will be executed. Handlers only handle exceptions that occur in the corresponding try clause, not in other handlers of the same try statement. An except clause may name multiple exceptions as a parenthesized tuple.

Objects

Assignment always copies the value of an expression, but a value is not always what you might expect it to be. In particular, the “value” of a structured object such as a list is actually just a reference to the object.
Python provides two ways to check that a pair of items are the same. == and is. The is operator tests for object identity.
We can use id() function to find out the numerical identifier for any object.

Some tips

The Zen of Python

import this

The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren’t special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one— and preferably only one —obvious way to do it.
Although that way may not be obvious at first unless you’re Dutch.
Now is better than never.
Although never is often better than right now.
If the implementation is hard to explain, it’s a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea — let’s do more of those!


The keyword argument end can be used to avoid the newline after the output, or end the output with a different string.

1
2
3
4
5
6
>>> a, b = 0, 1
>>> while b < 1000:
... print(b, end=',')
... a, b = b, a+b
...
1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,

in keyword tests whether or not a sequence contains a certain value.


The square brackets in the method signature denote that the parameter is optional, not that you should type square brackets at that position. This is frequent in the Python Library Reference.


Looping Techniques

When looping through dictionaries, the key and corresponding value can be retrieved at the same time using the items() method.

1
2
3
4
>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
>>> for k, v in knights.items():
... print(k, v)
...

When looping through a sequence, the position index and corresponding value can be retrieved at the same time using the enumerate() function.

1
2
3
4
5
6
>>> for i, v in enumerate(['tic', 'tac', 'toe']):
... print(i, v)
...
0 tic
1 tac
2 toe

To loop over two or more sequence at the same time, the entries can be paired with the zip() function.

1
2
3
4
5
6
7
8
>>> 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.

To loop over a sequence in reverse, first specify the sequence in a forward direction and then call the reversed() function.

1
2
3
>>> for i in reversed(range(1, 10, 2)):
... print(i)
...

To loop over a sequence in sorted order, use the sorted() function which returns a new sorted list while leaving the source unaltered.

1
2
3
4
>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> for f in sorted(set(basket)):
... print(f)
...

Eval

Eval: Built-in Function
The return value is the result of the evaluated expression. Syntax errors are reported as exceptions.
This function can also be used to execute arbitrary code objects (such as those created by compile()). In this case pass a code object instead of a string.

Split with multiple delimiters

See my post Regular Expression.

Execution time measurement

Measure execution time of small code snippets
timeit
timeit provides a simple way to time small bits of Python code.
Command-Line Interface:

1
2
3
4
5
6
$ python3 -m timeit '"-".join(str(n) for n in range(100))'
10000 loops, best of 5: 30.2 usec per loop
$ python3 -m timeit '"-".join([str(n) for n in range(100)])'
10000 loops, best of 5: 27.5 usec per loop
$ python3 -m timeit '"-".join(map(str, range(100)))'
10000 loops, best of 5: 23.2 usec per loop

Python Interface:

1
2
3
4
5
6
7
>>> import timeit
>>> timeit.timeit('"-".join(str(n) for n in range(100))', number=10000)
0.3018611848820001
>>> timeit.timeit('"-".join([str(n) for n in range(100)])', number=10000)
0.2727368790656328
>>> timeit.timeit('"-".join(map(str, range(100)))', number=10000)
0.23702679807320237

(In NLTK, it is introduced to use timeit.Timer, but that’s not necessary. timeit.timeit() will automatically create a Timer instance.)
timeit.timeit(stmt='pass', setup='pass', timer=<default timer>, number=1000000, globals=None)

The global parameter is new in Python 3.5. Passing globals() to the global parameter will cause the code to be executed within the current global namespcae. This can be more convenient than individually specifying imports.

General
https://docs.python.org/3.7/library/time.html?highlight=timer#time.process_time
Use time.process_time() method (which is new in Python 3.3) to record the beginning and end time.

1
2
3
4
5
import time
start = time.process_time()
# code execution
end = time.process_time()
print(end - start)

And for accuracy, Python 3.7 introduces process_time_ns() which return time as nanoseconds.

Python 2 to 3

2to3 is a Python program that reads Python 2.x source code and applies a series of fixers to transform it into valid Python 3.x code. 2to3 will usually be installed with the Python interpreter as a script.
2to3’s basic arguments are a list of files or directories to transform.
2to3 example.py
A diff against the original source file is printed. 2to3 can also write the needed modifications right back to the source file. Writing the changes back is enabled with the -w flag:
2to3 -w example.py
2to3 document

Something to be detailed

Here stores something that is introduced in tutorial briefly, waiting to be discussed in detail in the future.

Arbitrary Argument Lists and Unpacking Argument Lists
Introduced in Section 4.7,

Method
A method is a function that ‘belongs’ to an object and is named obj.methodname, where obj is some object (this may be an expression), and methodname is the name of a method that is defined by the object’s type. Different types define different methods. Methods of different types may have the same name without causing ambiguity.

Lambda Expressions
Small anonymous functions can be created with the lambda keyword. This function returns the sum of its two arguments: lambda a, b: a+b. Lambda functions can be used wherever function objects are required. They are syntactically restricted to a single expression. Semantically, they are just syntactic sugar for a normal function definition. Like nested function definitions, lambda functions can reference variables from the containing scope:

1
2
3
4
5
6
7
8
>>> def make_incrementor(n):
... return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43

The del statement
Remove an item from a list given its index instead of its value. The del statement can also be used to remove slices from a list or clear the entire list.

1
2
3
4
5
6
7
8
9
10
>>> a = [-1, 1, 66.25, 333, 333, 1234.5]
>>> del a[0]
>>> a
[1, 66.25, 333, 333, 1234.5]
>>> del a[2:4]
>>> a
[1, 66.25, 1234.5]
>>> del a[:]
>>> a
[]

del can also be used to delete entire variables.
del can delete a key:value pair in dict, the parameter is just dict’s key.