Part 1 - Python Cheatsheet - Basics
All the basics you need to know to get started in Python.
The following is Part 1 in a series of Python cheatsheets I put together while learning the language a little while ago. I am planning to release the other sections in the order below. Hope you find them useful.
- Basic Data Types and Logic
- tbc: OOP
- tbc: Functional Programming
- tbc: Decorators, Error Handling and Generators
- tbc: Modules
- tbc: Regular Expressions
- tbc: File I/O
- tbc: Testing
- tbc: Use Cases - Scripting, ML, Web Development
Basic Data Types
There are 9 basic data types
- Numbers →
int
,float
,complex
- Strings →
str
- Boolean →
bool
- Tuples →
tuple
- Lists →
list
- Sets →
set
- Dictionaries →
dict
- None →
none
(similar to null in JS)
Best Practice
Best practice for assigning data types to variables
- snake_case
- Cannot use hyphens (my-var will give error)
- Start with lowercase or underscore
- Static/constant variables should be all upper case (
PI = 3.14
) - As Python is dynamically typed, variables can be easily overwritten
- But Python is strongly typed so operations will fail if the variable is not the correct type.
- Dunder variables are default python variables - typically used to store metadata or are built into the system
Terminology
a = b / c
a
→ variableb / c
→ expressiona = b / c
→ statement
Number
# Arithmetic
10 + 3 # 13
10 - 3 # 7
10 * 3 # 30
10 ** 3 # 1000
10 / 3 # 3.3333333333333335
10 // 3 # 3 -> floor division - no decimals and returns an int
10 % 3 # 1 -> modulo operator - return the reminder. Good for deciding if number is even or odd
# augmented assignment operator
a = 3
a += 2 # 5
a -= 2 # 3
# Basic Functions
pow(5, 2) # 25 --> like doing 5**2
abs(-50) # 50
round(5.46) # 5
round(5.468, 2)# 5.47 --> round to nth digit
bin(512) # '0b1000000000' -> binary format
hex(512) # '0x200' -> hexadecimal format
# there a loads more available ...
String
Basic use and access
# Strings are immutable so you cannot change a certain index
a = 'abc'
a[1] = 'd' # this will fail
"\n" # new line
"\t" # adds a tab
# Multi line string
long_string = '''
This is a long string over multiple lines
'''
# String concatenation
'Hi there ' + 'Timmy' # 'Hi there Timmy'
'*'*10 # **********
String Indexes
# Follows ... var[start:stop:stepover]
name = 'John Doe'
name[4] # e
name[:] # John Doe -> full string same as name[::1]
name[1:] # John Doe
name[:1] # J -> same as name[0:1] and name[0]
name[-1] # e
name[::1] # John Doe
name[::-1] # eoD nhoJ
name[0:8:2] # Jh o -> Every second character
# : is called slicing and has the format [ start : end : step ]
String built-in methods
- Remember: Methods are functions that belong to something (in this case - a string)
- Functions can be stand alone
- As string is immutable, these methods return a new string.
# Basic Functions
len('turtle') # 6
# Basic Methods
' I am alone '.strip() # 'I am alone' --> Strips all whitespace characters from both ends.
'On an island'.strip('d') # 'On an islan' --> # Strips all passed characters from both ends.
'but life is good!'.split() # ['but', 'life', 'is', 'good!']
'Help me'.replace('me', 'you') # 'Help you' --> Replaces first with second param
'Need to make fire'.startswith('Need')# True
'and cook rice'.endswith('rice') # True
'bye bye'.index('e') # 2
'still there?'.upper() # STILL THERE?
'HELLO?!'.lower() # hello?!
'ok, I am done.'.capitalize() # 'Ok, I am done.'
'oh hi there'.find('i') # 4 --> returns the starting index position of the first occurrence
'oh hi there'.count('e') # 2
print(f'Hello there {name1} and {name2}') # Hello there Andrew and Sunny - Newer way to do things as of python 3.6
print('Hello there {}, {}'.format(name1, name2)) # Hello there Andrew and Sunny
print('Hello there %s and %s' %(name1, name2)) # %d, %f, %r for integers, floats, string
Converting str, int, float
Strings are generated in a simple manner
# Converting Strings to Numbers
age = 3 # 3
f_age = float(age) # 3.0
str_age = str(age) # "3"
int_age = int(str_age) # 3
Collections
List, Dictionary, Set, Tuple are all known as collections (i.e. a grouping of basic data types)
- List is a collection which is ordered and changeable/mutable. Allows duplicate members.
- Tuple is a collection which is ordered and unchangeable/immutable. Allows duplicate members.
- Set is a collection which is unordered, unindexed and changeable/mutable. No duplicate members.
- Dictionary is a collection which is ordered and changeable/mutable. No duplicate members.
Lists
- Similar to Arrays in other languages
- Lists are mutable in python → they will reuse reference pointers unless you clone it
- Sortable
Basic List
my_list = [1, 2, '3', True] # We assume this list won't mutate for each example below
len(my_list) # 4
my_list.index('3') # 2
my_list.count(2) # 1 --> count how many times 2 appears
List Slicing
- Works similar to strings
- Creates a new list → does not mutate
list_name[start:end:step]
my_list = [1, 2, '3', 'test']
my_list[3] # 'test'
my_list[1:] # [2, '3', 'test']
my_list[:1] # [1]
my_list[-1] # 'test'
my_list[::1] # [1, 2, '3', 'test']
my_list[::-1] # [True, '3', 2, 1]
my_list[0:3:2] # [1, '3']
**# Get First and Last element of a list**
mList = [63, 21, 30, 14, 35, 26, 77, 18, 49, 10]
first, *x, last = mList
print(first) #63
print(last) #10
Manipulating Lists
**# ADD TO LIST**
my_list * 2 # [1, 2, '3', True, 1, 2, '3', True]
my_list + [100] # [1, 2, '3', True, 100] --> doesn't mutate original list, creates new one
my_list.append(100) # None --> Mutates original list to [1, 2, '3', True, 100] # Or: <list> += [<el>]
my_list.extend([100, 200]) # None --> Mutates original list to [1, 2, '3', True, 100, 200]
my_list.insert(2, '!!!') # None --> [1, 2, '!!!', '3', True] - Inserts item at index and moves the rest to the right.
' '.join(['Hello','There']) # 'Hello There' --> Joins elements using string as separator.
**# COPY LIST **** VERY IMPORTANT WHEN USING LISTS ******
basket = ['apples', 'pears', 'oranges']
new_basket = basket.copy()
new_basket2 = basket[:]
**# REMOVE FROM LIST**
[1,2,3].pop() # 3 --> mutates original list, default index in the pop method is -1 (the last item)
[1,2,3].pop(1) # 2 --> mutates original list
[1,2,3].remove(2)# None --> [1,3] Removes the value that we give
[1,2,3].clear() # None --> mutates original list and removes all items: []
del [1,2,3][0] #
Ordering / Sorting
[1,2,5,3].sort() # None --> Mutates list to [1, 2, 3, 5]
[1,2,5,3].sort(reverse=True) # None --> Mutates list to [5, 3, 2, 1]
[1,2,5,3].reverse() # None --> Mutates list to [3, 5, 2, 1]
sorted([1,2,5,3]) # [1, 2, 3, 5] --> new list created
list(reversed([1,2,5,3])) # [3, 5, 2, 1] --> reversed() returns an iterator
names.sort(key=lambda name: name.split(' ')[-1].lower()) # We can use a lambda to change what sort uses as its key
sorted_by_second = sorted(['hi','you','man'], key=lambda el: el[1]). # ['man', 'hi', 'you']
sorted_by_key = sorted(
[
{'name': 'Sam', 'age': 30},
{'name': 'Mark', 'age': 18},
{'name': 'Amy', 'age': 55}
],
key=lambda el: (el['name'])
)
# [{'name': 'Mark', 'age': 18}, {'name': 'Sam', 'age': 30}, {'name': 'Amy', 'age': 55}]
Matrices (List of Lists)
matrix = [[1,2,3], [4,5,6], [7,8,9]]
matrix[2][0] # 7 -> Grab the first of the third item in the matrix object
**# Looping through a matrix by rows:**
mx = [[1,2,3],[4,5,6]]
for row in range(len(mx)):
for col in range(len(mx[0])):
print(mx[row][col]) # 1 2 3 4 5 6
**# Transform into a list:**
[mx[row][col] for row in range(len(mx)) for col in range(len(mx[0]))] # [1,2,3,4,5,6]
**# Combine columns with zip and *:**
[x for x in zip(*mx)] # [(1, 3), (2, 4)]
List Comprehensions
new_list[<action> for <item> in <iterator> if <some condition>]
a = [i for i in 'hello'] # ['h', 'e', 'l', 'l', '0']
b = [i*2 for i in [1,2,3]] # [2, 4, 6]
c = [i for i in range(0,10) if i % 2 == 0]# [0, 2, 4, 6, 8]
Useful Operations
my_list.index('item'). # finds index of 'item' in list
my_list.index('item', 0, 3) # finds index of 'item' in list[0:3]
****1 in [1,2,5,3] # True
min([1,2,3,4,5]) # 1
max([1,2,3,4,5]) # 5
sum([1,2,3,4,5]) # 15
list_of_chars = list('Helloooo') # ['H', 'e', 'l', 'l', 'o', 'o', 'o', 'o']
num = list(range(2)) # [0, 1]
nums2 = list(range(2,5)) # [2, 3, 4, 5]
nums3 = list(range(0,10,2)) # [0, 2, 4, 6, 8]
join = zip([1,2,3],[4,5,6]) # join to lists into tuples [(1, 4), (2, 5), (3, 6)]
element_sum = [sum(pair) for pair in zip([1,2,3],[4,5,6])] # [5, 7, 9]
**# Read line of a file into a list**
with open("myfile.txt") as f:
lines = [line.strip() for line in f]
Dictionary
- This is a Data Type but also a Data Structure (same as Lists)
- Similar to Objects in JS
- Also known as mappings or hash tables.
- They are key value pairs that are guaranteed to retain order of insertion starting from Python 3.7
- Not sortable
- Mutable
Basics
my_dict = {
'name': 'John Doe',
'age': 30,
'magic_power': False
}
**# Keys and Values**
my_dict['name'] # John Doe
len(my_dict) # 3
list(my_dict.keys()) # ['name', 'age', 'magic_power']
list(my_dict.values()) # ['John Doe', 30, False]
list(my_dict.items()) # [('name', 'John Doe'), ('age', 30), ('magic_power', False)]
**# Add or Assign**
my_dict['favourite_snack'] = 'Grapes' # {... 'favourite_snack': 'Grapes'}
**# Get**
my_dict['age']
my_dict.get('age') # 30 --> Returns None if key does not exist.
my_dict.get('ages', 0) # 0 --> **Returns default** (2nd param) if key is not found
**# Remove**
del my_dict['name']
my_dict.pop('name', None)
Other dict methods
my_dict.update({'cool': True})
# {'name': 'John Doe', 'age': 30, 'magic_power': False, 'favourite_snack': 'Grapes', 'cool': True}
{**my_dict, **{'cool': True} }
# Using destructuring to create a **new dict**
# {'name': 'John Doe', 'age': 30, 'magic_power': False, 'favourite_snack': 'Grapes', 'cool': True}
new_dict = dict([['name','Andrew'],['age',32],['magic_power',False]])
# Creates a dict from collection of key-value pairs.
new_dict = dict(zip(['name','age','magic_power'],['Andrew',32, False]))
# Creates a dict from two collections.
new_dict = my_dict.pop('favourite_snack')
# Removes item from dictionary.
my_dict.clear()
my_dict.copy()
my_dict.fromkeys()
my_dict.popitem()
my_dict.setdefault()
# Dictionary Comprehension
{key: value for key, value in new_dict.items() if key == 'age' or key == 'name'}
# {'name': 'Andrew', 'age': 32} --> Filter dict by keys
Tuple
- Denoted by brackets
('age', 30)
- Tuple is an immutable and hash-able list.
- Hash-able means that the value does not change during its lifetime. This allows Python to create a unique hash value to identify it.
- More performant than Lists
- **Immutable (cannot be changed, sorted, reversed, etc..)
- **Ordered
my_tuple = ('apple','grapes','mango', 'grapes')
apple, grapes, mango, grapes = my_tuple # Tuple unpacking
my_tuple[2] # mango
my_tuple[-1] # 'grapes' --> last item
x,y, *other = my_tuple # x = 'apple', other = ['mango', 'grapes']
len(my_tuple) # 4
**# Immutability**
my_tuple[1] = 'donuts' # TypeError
my_tuple.append('candy') # AttributeError
**# Methods (only 2 exist)**
my_tuple.index('grapes') # 1
my_tuple.count('grapes') # 2
**# Zip**
list(zip([1,2,3], [4,5,6])) # [(1, 4), (2, 5), (3, 6)]
**# Unzip**
z = [(1, 2), (3, 4), (5, 6), (7, 8)] # Some output of zip() function
unzip = lambda z: list(zip(*z))
unzip(z)
Named Tuple
- Named tuple is its subclass with named elements.
- Promotes easy editing and reusability
from collections import namedtuple
Point = namedtuple('Point', 'x y')
p = Point(1, y=2)# Point(x=1, y=2)
p[0] # 1
p.x # 1
getattr(p, 'y') # 2
p._fields # Or: Point._fields #('x', 'y')
Person = namedtuple('Person', 'name height')
person = Person('Jean-Luc', 187)
f'{person.height}' # '187'
'{p.height}'.format(p=person)# '187'
Sets
- Denoted with curly brackets
my_set = {1,2,3,4,5}
- Unordered
- Unique elements
- Mutable
- Unindexed (cannot be accessed like lists
myset[0] # error
)
my_set = set()
my_set = {1,2,3,4,5}
Methods
new_list = [1,2,3,3,3,4,4,5,6,1]
new_set = set(new_list)
my_set.add(1) # {1}
my_set.add(100) # {1, 100}
my_set.add(100) # {1, 100} --> no duplicates!
my_set.remove(100) # {1} --> Raises KeyError if element not found
my_set.discard(100) # {1} --> Doesn't raise an error if element not found
my_set.clear() # {}
1 in my_set # True
new_set = {1,2,3}.copy() # {1,2,3}
set1 = {1,2,3}
set2 = {3,4,5}
set1.update(set2) # {1,2,3,4,5}
set3 = set1.union(set2) # {1,2,3,4,5}
set3 = set1 | set2 # {1,2,3,4,5}
set4 = set1.intersection(set2) # {3}
set4 = set1 & set2 # {3}
set5 = set1.difference(set2) # {1, 2}
set6 = set1.symmetric_difference(set2)# {1, 2, 4, 5}
set1.issubset(set2) # False
set1.issuperset(set2) # False
set1.isdisjoint(set2) # False --> return True if two sets have a null intersection.
**# Frozenset**
# hashable --> it can be used as a key in a dictionary or as an element in a set.
<frozenset> = frozenset(<collection>)
Any / All
any([False, True, False])# True if at least one item in collection is truthy, False if empty.
all([True,1,3,True]) # True if all items in collection are true
Basic Logic
Comparison Operators
== # equal values
is # eqaulity of variable
!= # not equal
not( expression ) # checks for false
> # left operand is greater than right operand
< # left operand is less than right operand
>= # left operand is greater than or equal to right operand
<= # left operand is less than or equal to right operand
<element> is <element> # check if two operands refer to same object in memory
Logical Operators
==
checks for equalityis
checks if the location in memory is the same (Python will put simple data types in the same location)
1 < 2 and 4 > 1 # True
1 > 3 or 4 > 1 # True
a = 2
b = 1 + 1
a is b # True
a is not b # False
[] is [] # False (data structures are placed in new locations in memory)
not True # False
a not in [2,3,4] # False
a in [2,3,4] # True
**# is vs ==**
a = 'test'
b = ['test']
c = ['test']
b is c # False
b[0] is c[0] # True
b == c # True
# ----------
**# IF statement**
if <condition that evaluates to boolean>:
# perform action1
elif <condition that evaluates to boolean>:
# perform action2
else:
# perform action3
**# Shorthand**
if 5 > 2: print("Yes")
Loops
- Iterable data types →
str
,list
,dict
,tuple
,set
- When looping, ’_’ uis often used as the variable
for _ in range(0, 10):
my_list = [1,2,3]
my_tuple = (1,2,3)
my_list_of_tuples = [(1,2), (3,4), (5,6)]
my_dict = {'a': 1, 'b': 2. 'c': 3}
# FOR
for num in my_list:
print(num) # 1, 2, 3
for num in my_tuple:
print(num) # 1, 2, 3
for num in my_list_of_tuples:
print(num) # (1,2), (3,4), (5,6)
for num in '123':
print(num) # 1, 2, 3
for k,v in my_dict.items(): # Dictionary Unpacking
print(k) # 'a', 'b', 'c'
print(v) # 1, 2, 3
# WHILE
while <condition that evaluates to boolean>:
# action
if <condition that evaluates to boolean>:
break # break out of while loop
elif <condition that evaluates to boolean>:
continue # continue to the next line in the block
else:
# do something
# WHILE ELSE
while i < 6:
print(i)
i += 1
else:
print('not true any more')
# Example: waiting until user quits
msg = ''
while msg != 'quit':
msg = input("What should I do?")
print(msg)
Break, Continue, Pass
- Break → leave the loop
- Continue → go to the next pass of the loop
- Pass → does nothing, used as placeholder to keep going in a function
Range and Enumerate
- Often used in Python when looping
- enumerate gives you access to the item index
range(10) # range(0, 10) --> 0 to 9
range(1,10) # range(1, 10)
list(range(0,10,2))# [0, 2, 4, 6, 8]
for i, el in enumerate('helloo'):
print(f'{i}, {el}')
# 0, h
# 1, e
# 2, l
# 3, l
# 4, o
# 5, o
Walrus Operator
- Assigns values to variables as part of a larger expression
- Avoid duplication of common methods
a = 'helloooooooo'
# Here len(a) is run twice
if (len(a) > 10):
print(f"too long {len(a)}")
# Here, walrus operator allows us to assign len(a) to a variable
if ((n := len(a)) > 10):
print(f"too long {n}")
Ternary Operator/Condition
<expression_if_true> if <condition> else <expression_if_false>
# condition_if_true if condition else condition_if_else
age_based_msg = 'you are old' if is_old else 'you are young'
[a if a else 'zero' for a in [0, 1, 0, 3]] # ['zero', 1, 'zero', 3]
Functions
- Should do one thing very well
- Should return something
-
Python has function scope
- Variables defined in a function are not available globally
- In a function, global variables will not be overwritten
- If a variable not available locally, it will then check outside the scope
-
Scope rules follow four levels:
- Local (in the current function)
- Parent
- Global
- Built-in
- Function code is garbage collected by the Python interpreter
Basics
def my_function():
# do something here
**# Parameters** (the values a function takes when being defined)
def my_function(name, age):
# ...
**# Arguments** (the values provided to a function when invoked)
****my_function('Tom', 28)
**# Named Arguments** (order does not matter now)
my_function(age=28**,** name='Tom')
**# Default Parameters**
def my_function(name='My Default Name', age=23):
# ...
**# RULES FOR PARAMS** (format for using parameters in a function)
**def my_func(params, *args, default params, **kwargs)**
Comment / Docstring
def check_driver_age(age=0):
'''
This checks a drivers age
'''
# function code here
**# Print the function comment**
help(check_driver_age)
print(check_driver_age.__doc__)
args and **kwargs
Outside Function
- Splat (*) expands a collection (tuple) into positional arguments
- Splatty-splat (**) expands a dictionary into keyword arguments.
args = (1, 2)
kwargs = {'x': 3, 'y': 4, 'z': 5}
some_func(*args, **kwargs) # same as some_func(1, 2, x=3, y=4, z=5)
Inside Function Definition
- Splat combines zero or more positional arguments into a tuple.
- Splatty-splat combines zero or more keyword arguments into a dictionary.
def add(*a):
return sum(a)
add(1, 2, 3) # 6
Global Variables
- To use a variable from outside the function, you use the
global
keyword - You could also pass in the global variable as a param (called dependency injection)
total = 0
def add_one():
global total
total += 1
return total
Nonlocal
- Reference a variable that is in the parent scope (but not global)
x = 'global_var'
def outer():
x = 'outer_var'
def inner():
nonlocal x
x = x + ' - inner var'
print(x)
outer() **# "outer_var - inner var"**
print(x) **# "global_var"**
Lambda
- Defines an anonymous function (a function with no name)
- Often used for short math algorithms
lambda: <return_value>
lambda <argument1>, <argument2>: <return_value>
**# Example: Factorial**
from functools import reduce
n = 3
factorial = reduce(lambda x, y: x*y, range(1, n+1))
print(factorial) #6
**# Example: Fibonacci**
fib = lambda n : n if n <= 1 else fib(n-1) + fib(n-2)
result = fib(10)
print(result) #55