Python Basics
Python Basics: Essentials, Data Structure, Collections
Essentials
Math
import math
# when you need a infinite max min value: note that this returns floats
math.inf
-math.inf
# log
math.log()
# random integer N such that a <= N <= b.
random.randint(a, b)
# random item from a list
random.choice(l)
# randomly shuffle a list of nums in place
random.shuffle(nums)
Exceptions
try:
int(i)
except Exception as e:
print(e)
- loops
# you can't modify the i variable inside a for loop. eg. won't work:
for i in range(6):
i -= 1
lambda
x = lambda a, b, c : a + b + c
print(x(5, 6, 2))
# sort a 2d list by increasing of first number, and then increasing of second. eg. [7,0],[4,4],[7,1]
sorted_list = sorted(original_list, key=lambda x: (x[0], x[1]))
# filter
final_list = list(filter(lambda x: (x%2 != 0) , li)) # filters out to get all odd nums in li
# map
final_list = list(map(lambda x: x*2 , li)) # applie *2 to all the elements of the list
# reduce
from functools import reduce
sum = reduce((lambda x, y: x + y), li) # sum of the list
Class
class Dog:
all_tricks = [] # class instance shared by all dogs
def __init__(self, name):
self.name = name
self.tricks = [] # creates a new empty list for each dog
def add_trick(self, trick):
self.tricks.append(trick)
Enum
from enum import Enum
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
print(Color.RED) # Color.RED
print(Color.RED.name) # RED
print(Color.RED.value) # 1
Swapping
a, b, c = d, e, f
# note that order matters curr has to be last:
# eg. when reversing a list in leetcode/leet_0206_reverse-linked-list.py
# curr.next, prev, curr = prev, curr, curr.next
Data structures
- Time: https://wiki.python.org/moin/TimeComplexity
Char
# char to ascii value
ord(c)
# ascii value to char
chr(x)
# ascii value offset from 'a'
ord(c) - ord('a')
String
- Strings are immutable
# initialize
t = "string"
t = 'string'
# Operators
t + t
t * 3
# methods
t.isdigit() # if made of digits only
t.isalpha() # if made of alphabetics only
t.isalnum() # if made of digits and alphabetics only
t.isspace() # if made of spaces only
t.isupper() # if made of upper case only
t.upper() # returns an uppercased string
t.islower() # if made of lower case only
t.lower() # returns an lowercased string
t.swapcase() # toggle between lower and upper case for each char
# length
t.count("t") # count the occurance of the character t
len(t) #the length of the string
# aligning
t.center(20) # center the string in 20 chars
t.ljust(20) # left align in 20 chars
t.rjust(20) # right align in 20 chars
# strip
t.strirp() # strip trailing whitespaces
t.lstrip()
t.rstrip()
# replace
t.replace("a", "b") # replace all occurances of a to b
t.replace("a", "b", 2) # replace only the first 2
# split
t.plit("a") # returns a list of strings split by the seperator
# find
t.startswith("a") # if the string starts with
t.endswith("a") # is the string ends with
t.find("a") # returns the index of the first occurance
t.count('a') # returns the occurance of this string
# join
' '.join(["this", "is", "it"])
# reverse a string
str[::-1] # [ <first element to include> : <first element to exclude> : <step> ]
''.join(reversed(str))
# casting a binary string to int
int('110', 2)
# zfill with zeros
txt = "10"
x = txt.zfill(4) # 0010
# int to binary string - cut the first 2 chars
bin(3)[2:]
List
- same as arrays in java
# initilizing
l = [1, 2, 3]
l = [1] * 4 # create a list of four 1s
# insert and delete
l.append(4) # appends one element to the end of the list
l.extend([4, 5]) # This does not return another, but adds a list to l in place [Plus One](leetcode/leet_0066_plus-one.py)
l += [4, 5] # extends the list
l.insert(2, 99) # insert the element 99 before the given index 2
l.remove(99) # removes the first occorance of the given element
l.pop(0) # pop the first element of the list
l.pop() # pop the last element of the list
l.clear() # clears the whole list
# find
l.index(1) # return the index of the given element: 0
l.count(2) # count the number of the element
# sort
l.sort() # in place sorting
l.sort(reverse=True) # reverse sorting
l.reverse() # reverse the list in place
l[::-1] # reverse slice to return a reversed list
sorted(l, key=lambda x: len(x))# sort by length of string
# which is: [ <first element to include> : <first element to exclude> : <step> ]
# so is actually l[n-1:-1:-1]
sorted(l) returns a sorted list of l
# sublist
l[1:] # sublist from including index 1 to the end [2, 3]
l[:1] # sublist from the begining to and not include index 1 [1]
l[1:-1] # sublist from including index 1 to the including 1 from the end [2]
# list comprehension
[ x * 2 for x in l] # list processing [2, 4, 6]
[ x for x in l if x < 2 ] # list filtering [1]
# copy
l2 = l[:] # shallow copy
import copy
l2 = copy.deepcopy(l) # deep copy
l2 = l # reference only
l2[:] = l1[:] # by value
# insert into a sorted list
import bisect
bisext.insort(l, 0) # inserts the element 0 into the list
# enumerate both the index and the iterable
for i, num in enumerate(nums):
# zip : zips togeter multiple list by the element
[sum(x) for x in zip(l1, l2)] # sums the 2 lists l1 and l2 element wise
# initilizing a 2d list
dp = [[0] * m for x in range(n)]
# dp = [[0] * m] * n # NOPE: This makes a list with five references to the same list
Tuple
- Better way of mixing types in a collection
- Tuples are faster and consume less memory than list
- It is immutable
- Can be used as keys on a dictionary
# initilize
t = (1, 2, "a")
t = (1,) # tuple with a single element
t = (1,) * 3 # a tuple of five 1s
# manipulation
t += (9,) # append 9 to t
t[2:] # 2 index including to the end
# indexing
t.count(1) # count the number of occurances of 1
t.index(1) # find the first index of 1
# unpacking
a, b, c = t # can also return a tuple in a method and unpack to variables
# copy
t2 = t # tuple is immutabe and this creates a copy
# If a value within a tuple is mutable, then you can change it
t = (1, [9, 8]) # you can change t[1][0]
Dictionary
- Are not sorted
- Can not have duplicate elements
# initilize
d = {"a": 1, "b": 2}
a = {}.fromkeys(["a", "b"]) # creat a empty dictionary of None with the keys
# accessing
d.keys()
d.values()
d.items() # a list of tuple (key, value)
d["a"]
d.get("a")
d.get("a", -1) # get -1 as a default value
"a" in d # returns True or False
# manipulation
d.pop("a") # pop also removes the element
d.clear() # clear the dictionary
del d["a"] # deletes just one element
d2.update(d) # add all key values pairs of d to d2 , duplicated keys will be overwritten
# iterating
for key, value in d.items(): # iterate all key value
# counting items in list
counts = dict()
for i in items:
counts[i] = counts.get(i, 0) + 1
from collections import Counter
counts = Counter(items)
# sort by keys with highest first
sorted_list = sorted(freq.keys(), reverse=True)
Set
- unique elements
- ordering is arbitrary
- frozenset() is an immutable version of set
# initilize
a = set([1, 2, 3])
b = set([3, 4, 5])
# add
a.add(4)
# union
a | b # union
# intersection
a & b
a.intersection(b)
# subset
a < b
a.issubset(b)
a.issuperset(b)
# difference
a - b
a.differnece(b)
# symetric difference
a ^ b
a.symmetric_difference(b)
# copy
c = a.copy()
Heap
- priority queue
# creating it
import heapq
l = [5, 7, 9, 1, 3]
heapq.heapify(l) # min heap
heapq._heapify_max(l) # max heap
# pushing
heapq.heappush(l,4)
# pop
heapq.heappop(l) # min heap
heapq._heappop_max(l) # max heap
# access
heapq.nlargest(3, l) # returns a list of the 3 largest numbers
heapq.nsmallest(3, l) # returns a list of the 3 smallest numbers
# given counts which is a mup of num to counts: get the k most frequent numbers
heapq.nlargest(k, counts.keys(), key=counts.get)
PriorityQueue
- this is implemented as a wrapper around heap
- this is thread safe
- easier sytax
from queue import PriorityQueue
q = PriorityQueue()
q.put(1)
q.put(4)
q.put(2)
next_item = q.get()
q.qsize() # get size
# if want a reverse one as a max heap, use a tuple with the first one as the key: or use neg
q.put((-n ,n))
# peek:
q.queue[0]
Collections
- Counter
- defaultdict
- OrderedDict
- deque
- ChainMap
- namedtuple()
Counter
- give it a list and it will count occurances of each element and give dictionary of key => occurances
from collections import Counter
d = Counter([1,1,1,2]) # Counter({1: 3, 2: 1})
d[1] # 3
# get the original list:
list(b.elements()) # [1,1,1,2]
# sort the counter dictionary and give a sorted list of key-value
d.most_common() # [(1, 3), (2, 1)]
# subtract another dictionary: it will match the keys and subtract the values
d.subtract(d2)
defaultdict
- sets a default return value instead of throwing a
KeyError
when the key does not exist - easier to use d.get('two', 0) instead
from collections import defaultdict
nums = defaultdict(int)
nums['two'] = 2
print(nums['three']) # 0
OrderedDict
- a dictionary where keys maintain the order in which they are inserted
from collections import OrderedDict
d = OrderedDict()
d['a'] = 1
d['b'] = 2
d['c'] = 3
print(d) # OrderedDict([('a', 1), ('b', 2), ('c', 3)])
deque
- list that append pop from either end in O(1)
- python list pop(0) would otherwise be O(n)
from collections import deque
list = ["a","b","c"]
dq = deque(list)
print(dq) # deque(['a', 'b', 'c'])
# append
dq.append("d")
dq.appendleft("z")
# pop
dq.pop()
dq.popleft()
# other
dq.clear()
dq.count('a') # counts the number of occurances: 1
ChainMap
- combine multiple dictionaries to be used as a single unit
from collections import ChainMap
dict1 = { 'a' : 1, 'b' : 2 }
dict2 = { 'c' : 3, 'b' : 4 }
chain_map = ChainMap(dict1, dict2)
print(chain_map.maps) # [{'b': 2, 'a': 1}, {'c': 3, 'b': 4}]
print (list(chain_map.keys())) # ['b', 'a', 'c']
print (list(chain_map.values())) # [2, 1, 3]
chain_map.new_child(dict3) # add another dictionary
namedtuple()
- gives name to each object in tuple
from collections import namedtuple
Student = namedtuple('Student', 'fname, lname, age')
s1 = Student('John', 'Clarke', '13')
print(s1.fname) # Student(fname='John', lname='Clarke', age='13')
s2 = Student._make(['Adam','joe','18']) # creates new Student tuples
s2 = s1._replace(age='14') # changes a field of the tuple: tuples are immutable so this returns new instance