# Python Reference

by Chee Yee Lim

Posted on 2021-04-17

Collection of notes on key points for Python

## Overview

### General

• What are the key features of Python?
• General purpose language - capable of both programming and scripting.
• Interpreted language - does not need to be compiled into machine level code before running.
• High-level - highly readable and easy to write code.
• Dynamically typed - does not need explicit declaration of variable types.
• Good for object-oriented programming - allows the definition of classes along with composition and inheritance.
• Special properties of Python
• Python is a case sensitive programming language.
• Python starts indexing from 0.
• PEP 8 (Python Enhancement Proposal) specifies how to format Python code for maximum readability.
• PYTHONPATH is an environment variable used by Python to look up modules.
• Single line comments in Python start with hash #. Multi line comments are enclosed by """. """ is mostly used as docstrings (i.e. documentation strings) to explain the purpose of functions.
• Indentations are required in Python. A new block in Python begins when the line is indented by 4 spaces.
• Namespace
• A namespace is a naming system used to make sure that names are unique to avoid naming conflicts.
• Global and local variables
• Global variables are declared in the global space or outside a function. They are accessible by any function in the program.
• Local variables are declared in the local space of a function.

### Data types

• Standard data types of Python
• Numbers
• String
• Immutable
• Set
• An unordered collection of unique elements.
• List
• An ordered collection of elements.
• Tuple
• A tuple is an array of values, that is immutable (i.e. read only).
• Dictionary
• A dictionary consists of key-value pairs, in a hash table style.
• What are the differences between tuples and lists?
• The elements of a list can be updated.
• The size of a list can be updated.
• A tuple is slightly smaller than a list, hence give slightly faster performance.
• A tuple can be used as a key in a dictionary.
• What are the differences between sets and lists?
• Sets cannot contain duplicates.
• Sets are unordered.
• Sets are not indexed (i.e. elements unaccessible by index).
• Sets can only contain hashable items (e.g. can't have nested lists).
• What are the differences between arrays and lists?
• Python doesn't have built in array support.
• Arrays can only hold a single data type, while lists can hold any data types.
• What are the differences between lists and numpy arrays?
• Numpy arrays are more memory efficient.
• Numpy arrays are faster.
• Numpy arrays are more convenient due to developed methods.

### Functions

• What are functions?
• A function is a block of code which only runs when it is called.
• Data can be passed into a function as a parameter to an argument, and data can be returned from a function as a result.
• Lambda function
• lambda is a keyword in Python that creates an anonymous function.
• lambda can have any number of parameters but only one expression.
• *args vs **kwargs for function arguments
• *args is used when we don't know how many arguments will be passed to a function. The function will access the parameters by positions.
• **kwargs is used when we don't know how many keyword arguments will be passed to a function. The function will access the parameters by argument keywords.

### Classes/Objects

• __init__ constructor method
• It is automatically called to initialise a new object/instance of a class.
• All classes have the __init__ method.
• self
• self is an instance of a class.
• It is explicitly included as the first parameter.
• It helps to differentiate between the methods and attributes of a class with local variables.

### Flow control

• Break, continue, pass
• Break allows loop termination when some conditions are met and the control is transferred to the next statement.
• Continue allows skipping some part of a loop when some conditions are met and the control is transferred to the beginning of the loop.
• Pass is used when you need some block of code syntactically, but you want to skip its execution. It is basically a null operation, i.e. nothing happens when executed.

### Iterators/Iterables/Generators

• Iterators
• Iterators contain a countable number of values.
• Iterators are objects which can be iterated upon, meaning that you can traverse through all the values.
• Iterators in Python implement the iterator protocol, which consists of the methods __iter__() and __next__().
• Iterables
• List, tuples, dictionaries, sets and strings are all iterable objects.
• They are iterable containers which you can get an iterator from.
• E.g.  mystr = "banana" myit = iter(mystr)

print(next(myit)) print(next(myit)) - A for loop is typically used to iterate through an iterable object. - Generators - Functions that return an iterable set of items are called generators. -rangevsxrange - Range and xrange are exactly the same in terms of functionality. - The only difference is range returns a list object while xrange returns an xrange object. - xrange object is a generator, which saves memory by not materialising the whole array of values in the beginning.

### Copying variables

• Shallow copy - Shallow copy is used to copy the reference pointers just like it copies the values.
• Deep copy - Deep copy doesn't copy the reference pointers to the objects. It makes the reference to an object and the new object that is pointed by some other object gets stored.
• For primitive data types (e.g. int), reassignment of value to a new variable will not affect the values of the previous variable.
• E.g. x = 1 y = x y = 2 print(x) # it will be 1
• For data structure types, reassignment of value to an element within the variable will change the original value in the previous variable.
• E.g. x = [1,2] y = x y[1] = 9 print(x) # it will be [1,9]

• Python has a multi-threading package but if you want to multi-thread to speed your code up, then it's usually not a good idea to use it.
• Python has a construct called the Global Interpreter Lock (GIL). The GIL makes sure that only one of your 'threads' can execute at any one time.
• A thread acquires the GIL, does a little work, then passes the GIL onto the next thread.
• All this GIL passing adds overhead to execution. This means that if you want to make your code run faster, then using the threading package often isn't a good idea.