Table of Contents

Basic operations

>>> 3 / 2
1.5
>>> 3 // 2
1
>>> 3 ** 2
9
>>> abs(-1)
1

Basic Data Structures

List

  • Ordered
  • Changable
  • Duplicates
>>> list = []
>>> list = [i:j] # returns list subset
>>> list = [-1]  # returns last element

>>> list[i] = val
>>> list[i:j] = otherlist  # replace ith to jth element with otherlist
>>> del list[i:j]

>>> list.append(item)          # O(1) or O(n) in case of resizing
>>> list.extend(another_list)  # O(1) or O(n) in case of resizing
>>> list.insert(index, item)   # O(n)
>>> list.pop()                 # O(1) returns and removes last element from the list
>>> list.pop(i)                # O(n) returns and removes i-th element from the list
>>> list.remove(value)             # O(n) removes the first item from the list whose value is `value`
>>> list1 + list2              # combine two list    
>>> set(list)                  # remove duplicate elements from a list

>>> list.reverse()    # reverses the elements of the list in-place
>>> list.count(item)
>>> sum(list)

>>> zip(list1, list2)  # returns list of tuples with n-th element of both list1 and list2
>>> list.sort()        # sorts in-place, returns None
>>> sorted(list)       # returns sorted copy of list
>>> ",".join(list)     # returns a string with list elements separated by comma

Tuple

  • Ordered
  • Changable
  • Duplicates

Can be used as a dictionary key

>>> tuple = ("apple", "banana", "cherry")

>>> tuple[1] # banana
'banana'
>>> tuple.count()
3
>>> tuple.index("banana")
1

Set

  • Ordered
  • Changable
  • Duplicates

Cannot access by index

set = {"apple", "banana", "cherry"}

set.add("orange")
set.update(["orange", "mango", "grapes"])

# intersecton
{"a"} & {"a", "b"}
{'a'}

# union
{"a", "c"} | {"a", "b"}
{'b', 'a', 'c'}

# difference 
{"a", "c"} ^ {"a", "b"}
{'b', 'c'}

# create set of unique characters from the string 
set("aba")
{'b', 'a'}

Dict

  • Ordered
  • Changable
  • Duplicates
>>> dict.keys()
>>> dict.values()
>>> "key" in dict    # let's say this returns False, then...
>>> dict["key"]      # ...this raises KeyError
>>> dict.get("key")  # ...this returns None
>>> dict.setdefault("key", 1)

String

  • Changable
>>> str[0:4]
>>> len(str)

>>> string.replace("-", " ")   # find and replace
>>> ",".join(list)             # join list into string
>>> "hi {0}".format('j')       # format string
>>> str.find(",")              # find in the string
>>> str.index(",")             # same, but raises IndexError
>>> str.count(",")
>>> str.split(",")

>>> str.lower() # hello world
>>> str.upper() # HELLO WORLD 
>>> str.title() # Hello World

>>> str.lstrip() # left strip
>>> str.rstrip() # right strip
>>> str.strip()  # both

>>> str.islower() # is lower/upper/title

Loops And Iterations

>>> for item in ["a", "b", "c"]:
>>> for i in range(4):        # 0 to 3
>>> for i in range(4, 8):     # 4 to 7
>>> for i in range(1, 9, 2):  # 1, 3, 5, 7
>>> for key, val in dict.items():
>>> for index, item in enumerate(list):

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

>>> for q, a in zip(questions, answers):
...  print('What is your {0}?  It is {1}.'.format(q, a))

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

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

Sorting

>>> sorted([5, 2, 3, 1, 4]) # returns a new list
[1, 2, 3, 4, 5]

>>> a = [5, 2, 3, 1, 4]
>>> a.sort() # in-place sort
>>> a
[1, 2, 3, 4, 5]

Key Functions

Key function takes a single argument and returns a key to use for sorting purposes.

Case insesetive sorting using key function:

>>> sorted("This is a test string from Andrew".split(), key=str.lower)
['a', 'Andrew', 'from', 'is', 'string', 'test', 'This']

Sort by key of a tuple:

>>> student_tuples = [
...  ('john', 'A', 15),
...  ('jane', 'B', 12),
...  ('dave', 'B', 10),
... ]
>>> sorted(student_tuples, key=lambda student: student[2])
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

Extended Data Structures

Queue

While appends and pops from the end of list are fast, doing inserts or pops from the beginning of a list is slow (because all of the other elements have to be shifted by one). To implement a queue, use collections.deque which was designed to have fast appends and pops from both ends. For example:

>>> from collections import deque
>>> queue = deque(["Eric", "John", "Michael"])
>>> queue.append("Terry")           # Terry arrives
>>> queue.append("Graham")          # Graham arrives
>>> queue.popleft()                 # The first to arrive now leaves
'Eric'
>>> queue.popleft()                 # The second to arrive now leaves
'John'
>>> queue                           # Remaining queue in order of arrival
deque(['Michael', 'Terry', 'Graham'])

Linked List

class LinkedList:
  def __ini__(self):
    self.head = None
    self.tail = None

  def append(self, node):
    self.tail.next = node
    self.tail = node
  
  def prepend(self, node):
    node.next = self.head
    self.head = node

class Node:
  def __init__(self, val):
    self.val = val,
    self.next = None

Formulas

Number of substrings of a string

(n * (n + 1)) // 2 # where n is the number of characters