Python
Table of Contents
This is a list of various important and miscellaneous Python features that is helpful throughout the course.
1. Types
1.1. Primitive Types
The primitive types are the most basic types in Python and are immutable, which means their value cannot be changed without creating a new instance of that object.
x = 67 # integer
y = 3.14 # float
quit = False # boolean
name = "John" # string
1.2. Sequences
1.2.1. Slicing
digits = [1, 2, 3, 4, 5]
subdigits = digits[1:3] # [2, 3]
from_start = digits[:3] # [1, 2, 3]
to_end = digits[3:] # [4, 5]
1.2.2. Lists
odds = [41, 43, 47, 49]
a = odds[0] # 41
length = len(odds) # 4
b = sum([1, 2, 3]) # 6
c = sum([[1], [2, 3], [4]], []) # [1, 2, 3, 4]
- List Comprehension
newlist = [<expression> for <item> in <iterable> if <condition>] - List Mutation
suits = ['coin', 'string', 'myriad'] original_suits = suits s = suits.pop() # 'myriad', suits is now ['coin', 'string'] suits.remove('string') # suits is now ['coin'] suits.append('cup') # suits is now ['coin', 'cup'] suits.extend(['sword', 'club']) # suits is now ['coin', 'cup', 'sword', 'club'] suits[2] = 'spade' # suits is now ['coin', 'cup', 'spade', 'club'] suits[0:2] = ['heart', 'diamond'] # suits is now ['heart', 'diamond', 'spade', 'club'] # original_suits is also ['heart', 'diamond', 'spade', 'club']
1.2.3. Ranges
nums = [i for i in range(4)]
1.2.4. Strings
single = 'I am a string!'
double = "I've got an apostrophe"
hi = '您好'
# 'The Zen of Python\nclaims, Readability counts.\nRead more: import this.'
multi = """The Zen of Python
claims, Readability counts.
Read more: import this."""
1.2.5. Tuples
t = (3, 4, 5, 6)
l = tuple([3, 4, 5]) # (3, 4, 5)
single = (2,)
1.2.6. Aggregation
# sum(iterable[, start] -> value
a = sum([2, 3, 4]) # 9
b = sum([2, 3, 4], 5) # 14
c = sum([[2, 3], [4]], []) # [2, 3, 4]
# max(iterable[, key=func]) -> value
d = max(range(5)) # 4
s = ['a', 'aaa', 'aa']
longest = max(s, key=len) # 'aaa'
# all(iterable) -> bool
trues = [True, True, True]
istrue = all(trues) # True
# any(iterable) -> bool
some = [True, False, False]
istrue = any(some) # True
1.3. Dictionaries
Dictionaries are collections of key-value pairs: they map keys to values. There are two restrictions on dictionary keys:
- A key cannot be a list or a dictionary (or any mutable type)
- Two keys cannot be equal: there is only one value for one key
numerals = {'I': 1, 'V': 5, 'X': 10}
val = numerals['X'] # 10
keys = list(numerals) # ['I', 'V', 'X']
vals = numerals.values() # dict_values([1, 5, 10])
length = len(numerals) # 3
1.4. Dictionary Comprehensions
{<key>: <value> for <name> in <iterable> if <condition>}
2. Assignment
x = 4 / 3 # assignment
q, r = 4 // 3, 4 % 3 # multiple assignment
3. Operators
3.1. Mathematical Operators
a = 1 + 2 # addition
b = 2 - 1 # subtraction
c = 3 * 4 # multiplication
d = 4 / 3 # division (1.3333333 ...)
e = 4 // 3 # floor division (1)
f = 4 % 3 # modulus (1)
g = (1 + 2) * (3 + 4) # association
3.2. Comparison Operators
1 < 2 # less than
1 <= 2 # less than or equal to
2 > 1 # greater than
2 >= 1 # greater than or equal to
1 == 1 # equals to
2 != 1 # not equal to
3.3. Boolean Operators
True and True # and (True)
False or True # or (True)
not True # not (False)
4. Functions
4.1. Defining Functions
Functions consist of a function signature, which defines the name and a number of formal parameters. The function body is the part indented after the function signature:
def square(x):
return x ** 2
4.1.1. Nested Definitions
In higher-order functions, we can define new functions inside of a function. These are called nested definitions:
def make_adder(n):
def adder(k):
return k + n
return adder
4.1.2. Default Values
We can specify default values for some of the formal parameters to make them optional: if they are not specified, they will take on the default value:
def hello(name="World"):
print("Hello, " + name)
Evaluating just hello() would print Hello, World, but we can also specify other names with hello(name=<param>).
4.2. Lambda Expressions
We can use lambda expressions to return anonymous functions:
square = lambda x: x * x
4.3. Decorators
We can use higher-order functions to create decorators, which modify the behavior of a function with another function:
def trace(fn):
def traced(x):
print("Calling", fn, "on argument", x)
return fn(x)
return traced
@trace
def square(x):
return x * x
The @trace is a decorator. Essentially what it does is when you call square(x), what you're actually doing is trace(square)(x). In other words, the decorator is a shorthand for writing square = trace(square).
4.4. Docstrings
You can also add documentation to your functions by using docstrings. For example:
def square(x):
"""Returns the square of X."""
return x ** 2
4.5. Doctests
You can also add tests to your docstrings. For example:
def square(x):
"""Returns the square of X.
>>> square(2)
4
"""
return x ** 2
You can then run the doctests with python3 -m doctest <file.py>, optionally with -v for verbose output.
5. Conditional Statements
def absolute_value(x):
"""Return the absolute value of x."""
if x < 0:
return -x
elif x == 0:
return 0
else:
return x
6. Iteration
6.1. Iterators
s = [3, 4, 5]
t = iter(s)
first = next(t) # 3
second = next(t) # 4
6.1.1. Built-In Functions
map(<func>, <iterable>) # Iterate over func(x) for x in iterable
filter(<func>, <iterable>) # Iterate over x in iterable if func(x)
zip(<first_iter>, <second_iter>) # Iterate over co-indexed (x, y) pairs
reversed(<sequence>) # Iterate over x in a sequence in reverse order
6.1.2. Generators
def plus_minus(x):
yield x
yield -x
t = plus_minus(3) # generator
a = next(t) # 3
b = next(t) # -3
def a_then_b(a, b):
yield from a
yield from b
l = list(a_then_b([3, 4], [5, 6])) # [3, 4, 5, 6]
6.2. while
i, total = 0, 0
while i < 3:
i = i + 1
total = total + i
6.3. for
total = 0
for i in range(1, 4):
total = total + i
7. Assert
Can use assert to thrown an AssertionError if the assertion is false:
assert 2 > 3, 'That is false' # AssertionError: That is false
8. Type Hints
Python is dynamically typed, which means that names do not have types. A name can be assigned to something of one type and later assigned to a value of a different type.
However, it is often useful to use type hints, which tell a reader what type a program expects to receive/output:
x: int = 6
y: string = "seven"
z: float = 1.5
digits: list[int] = [1, 2, 3, 4, 5]
def identity(n: int) -> int:
return n
Python will not enforce the type hints, but it will warn you of any inconsistencies.
9. Classes
class Account:
interest = 0.02
def __init__(self, account_holder):
self.balance = 0
self.holder = account_holder
def deposit(self, amount):
self.balance = self.balance + amount
return self.balance
def withdraw(self, amount):
if amount > self.balance:
return 'Insufficient funds'
self.balance = self.balance - amount
return self.balance
a = Account('John')
b = Account('Jack')
assert a is not b
a.deposit(100)
10. String Interpolation
String interpolation in Python is achieved by evaluating a f-string, which is a string literal that contains expressions:
pi_string = f'pi starts with {pi}...' # 'pi starts with 3.141592653589793...'
num = f'2 + 2 = {(lambda x: x + x)(2)}' # '2 + 2 = 4'
11. Error Handling
We can catch exceptions in Python using try and except:
d = {1: 2}
try:
print(d[2])
except KeyError as e:
print(f"Error: {e}")
We can also raise exceptions with raise:
x = 0:
if x >= 0:
raise ValueError("Number must be negative")