Python helloworld:
print('hello world!')
Most unix/linux has python installed by default, you type "python" to enter the console.
>python
Python 3.7.3 (default, Nov 8 2020, 10:21:30)
[Clang 10.0.0 (clang-1000.10.44.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print('hello world!')
hello world!
>>>
Python variables:
You can assign a variable as int, bool, str, etc.
assuming a is a variable:
a = 1
a = True
a = 'hello'
>>> a = 1
>>> b = 2
>>> print(a+b)
3
>>> a = True
>>> b = False
>>> print(a and b)
False
>>> print(a or b)
True
>>> print(not a)
False
>>>
>>> a = 'hello'
>>> b = 'world'
>>> print(a+b)
helloworld
>>>
>>> a = 1
>>> b = 'hello'
>>> print(a + b)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
>>>
As we can see, we can add int to int, str to str, but we can not add int to str.
We can convert int to str
a = 1 #a'type is int
a = str(a) #a'type changes to str
We can also convert str to int
a = '3'
a = str(a)
>>> a = 1
>>> b = 'hello'
>>> print(str(a) + ' ' + b + '!')
1 hello!
>>>
>>> a = '3'
>>> b = '4'
>>> print(a+b)
34
>>> print(int(a)+int(b))
7
Common int related operations.
>>> print(2*3) #2x3=6
6
>>> print(2**3) #2x2x2=8
8
>>> print(5/2) #float division 5/2=2.5
2.5
>>> print(5//2) #integer division
2
>>> print(5%2) #integer reminder
1
>>> mid = (0+5)//2 #start index 0, end index 5, middle index 2
>>> print(mid)
2
>>> mid = (0+4)//2 #start index 0, end index 4, middle index 2
>>> print(mid)
2
>>> print(3|2) #bitwise or
3
>>> print(3&2) #bitwise and
2
>>> print(3^2) #bitwise nor
1
>>> print(3<<1) #bitwise left shift 1
6
>>> print(3>>1)
1
>>>
Python data structures:
Besides int, float, bool, str, we have data structures list, dict, we can build stack, queue, priority queue out from them.
a = [] #create an empty list
a.append('a')
a.append(1) #python list element can have mixed types
a.append(True)
a = {} #create an empty map/dict (dictionary)
a['a'] = 'a value'
a['b'] = 'b value'
>>>
>>> a = []
>>> a.append('a')
>>> a.append(1)
>>> a.append(False)
>>> print(a)
['a', 1, False]
>>> print(a[0])
a
>>> a.insert(1,'1')
>>> print(a)
['a', '1', 1, False]
>>> b = a.pop() #use as stack
>>> print(b)
False
>>> print(a)
['a', '1', 1]
>>> a.append([4, True])
>>> print(a)
['a', '1', 1, [4, True]]
>>> print(a[3][0])
4
>>> print(a.pop(0)) #use as queue
a
>>> print(a)
['1', 1, [4, True]]
>>>
>>> a.remove('1')
>>> print(a)
[1, [4, True]]
>>> a[1].remove(True)
>>> print(a)
[1, [4]]
>>> print(1 in a)
True
>>> print([4] in a)
True
>>> print(4 in a)
False
>>> print(a[1])
[4]
>>> print(a['1'])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: list indices must be integers or slices, not str
As we can see, we can add elements with append and insert, we can access element with index 0,1,2,3.... While append() add to the tail, pop() remove from the tail, pop(0) remove from head, with these functions, we can create stack and queue from list.
The list use an int as key to retrieve value, a[0] maps an int to an element. In the last example,
0 -> 1
1 -> [4]
In list, we can only use int as key, str '1' is not a valid key.
In map/dictionary the key can be any type, int, str, list, etc.
>>> a = {}
>>> a['key1'] = 'val1'
>>> a['key2'] = []
>>> print(a)
{'key1': 'val1', 'key2': []}
>>> print(a['key2'])
[]
>>> x = 'key1' in a
>>> print(x)
True
>>> print(a['key1'])
val1
>>> a['key1'] = 111000 #if key exists, update the existing entry
>>> print(a['key1'])
111000
>>> x = 'key3' in a
>>> print(x)
False
>>> a['key3'] = 'a new val3' #if key does not exist, a new entry is added to dic
>>> print(a)
{'key1': 111000, 'key2': [], 'key3': 'a new val3'}
>>>
>>> a['key2'].append('val2-0') #a['key2'] return the empty list [], append add an element to it
>>> print(a)
{'key1': 111000, 'key2': ['val2-0'], 'key3': 'a new val3'}
>>> print(a.popitem()) #remove an entry
('key3', 'a new val3')
>>> print(a)
{'key1': 111000, 'key2': ['val2-0']}
>>> print(a.pop('key1')) #remove an entry with key1
111000
>>> print(a)
{'key2': ['val2-0']}
>>> print(len(a)) #size of a
1
>>> print(len(a['key2'])) #size of list ['val2-0']
1
>>>
We can iterate through list entries.
for x in a:
print(a)
Here we meet a 2 line command. ":" and indents glue the lines. when you type : then enter, console knows you are not done yet. You press enter after type in print(a), with another enter, the 2 line command runs.
>>> a = [1,2,3,4]
>>> for x in a:
... print(x)
...
1
2
3
4
Alternatively, we can iterate the index and retrieve the list element with the index.
for i in rang(len(a)):
print(a[i])
>>> a = [1,2,3,4,'last one']
>>> size = len(a)
>>> print(size)
5
>>> for i in range(size):
... print(a[i])
... if i == size-1:
... print('done with the last index '+str(i))
...
1
2
3
4
last one
done with the last index 4
For map/dic, we iterate the keys, and retrieve the element with the key.
>>> a = {1: 'ok', '1': 2, 'a list': [1, 2, '3']}
>>> for key in a:
... print(key)
... print(a[key])
...
1
ok
1
2
a list
[1, 2, '3']
Python functions
In hello world, we called print('hello world') to print for us. print() is a build in function. We can define our own functions.
def functionName():
>>> def triangleArea(a, h):
... return a * h /2
...
>>> s = triangleArea(2, 2)
>>> print(s)
2.0
Python class/object
Python object, as the english meaning, is object we deal with. A class is a blueprint of creating objects. The syntax for class is
class className:
Once we have a class, we can create many objects with that class
className()
>>> class Person:
... firstname = ''
... lastname = '' #default value is empty str
...
>>> peter = Person()
>>> peter.firstname = 'Peter'
>>> peter.lastnmae = 'Andrenson' #typo
>>> tom = Person()
>>> tom.firstname = 'Tom'
>>> tom.lastname = 'Lee'
>>> print(peter.lastname)
>>> print(tom.lastname)
Lee
>>>
Class allow us to build data structures such as linked list, binary tree, graph.
>>> class LinkedListNode:
... val = 0
... next = None
...
>>> tail = LinkedListNode()
>>> tail.val = 4
>>> node3 = LinkedListNode()
>>> node3.val = 3
>>> node3.next = tail
>>> node2 = LinkedListNode()
>>> node2.val = 2
>>> node2.next = node3
>>> head = LinkedListNode()
>>> head.val = 1
>>> head.next = node2
>>>
>>> cur = head
>>> while cur is not None:
... print(cur.val)
... cur = cur.next
...
1
2
3
4
>>> class TreeNode:
... val = 0
... left = None
... right = None
...
>>> leaf1 = TreeNode()
>>> leaf2 = TreeNode()
>>> node = TreeNode()
>>> node.val = 2
>>> node.left = leaf1
>>> node.right = leaf2
>>> root = TreeNode()
>>> root.val = 1
>>> root.left = node
>>>
>>> def recursive(node):
... if node is None:
... return
... print(node.val)
... recursive(node.left)
... recursive(node.right)
...
>>> recursive(root)
1
2
0
0
>>> class GraphNode:
... val = 0
... neighbor = []
...
>>> node1, node2, node3 = GraphNode(), GraphNode(), GraphNode()
>>> node1.val, node2.val, node3.val = 1,2,3
>>> node1.neighbor, node2.neighbor, node3.neighbor = [node2,node3], [node1,node3], [node1, node2]
>>> def dfs(node, visited):
... print(node.val)
... visited.add(node)
... for nei in node.neighbor:
... if nei not in visited:
... dfs(nei, visited)
...
>>> dfs(node1, set())
1
2
3
We have met a few python build-in classes, str, list for example.
when we use shortcuts:
a = 'hello'
it is equivalent to
a = str('hello')
a = [1,2,3]
is equivalent to
a = list([1,2,3])
A class can have functions too. Let's look at list's sort function.
a.sort() #ascending
a.sort(reverse=True) #descending
a.sort(key = lambda x:x[0]) #for each element x, we want to use x[0] as sorting key
>>> a = [1,2,4,3]
>>> a.sort()
>>> print(a)
[1, 2, 3, 4]
>>> a.sort(reverse=True)
>>> print(a)
[4, 3, 2, 1]
>>> a = [[1,3],[2,2],[3,1]]
>>> a.sort() #default key is x[0]
>>> print(a)
[[1, 3], [2, 2], [3, 1]]
>>> a.sort(reverse=True) #sort by x[0] descending
>>> print(a)
[[3, 1], [2, 2], [1, 3]]
>>> a.sort(key=lambda x:x[1]) #sort by x[1] ascending
>>> print(a)
[[3, 1], [2, 2], [1, 3]]
>>> a.sort(key=lambda x:x[0])
>>> print(a)
[[1, 3], [2, 2], [3, 1]]
Useful python techniques
First let's meet a few python build in class.
set is a collection of objects without duplicate.
>>> a = set()
>>> a.add(1)
>>> a.add(2)
>>> a.add(1)
>>> print(len(a))
2
>>> print(a)
{1, 2}
>>> print(1 in a)
True
>>> a.remove(1)
>>> print(1 in a)
False
>>> print(a)
{2}
besides build in classes, we can use classes defined in python modules. In order to use a module.
import modulename
heapq allow us to build priority queue out of normal list.
>>> a = [1,2,3]
>>> heapq.heapify(a) #turn a into a heap/priority queue
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'heapq' is not defined
>>> import heapq #heapq is not a build in class, we need to import its containing module
>>> heapq.heapify(a)
>>> heapq.heappush(9)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: heappush expected 2 arguments, got 1
>>> heapq.heappush(a, 9) #add 9 to the heap stored in list a
>>> heapq.heappop(a) #pop the smallest element in heap stored in a
1
>>> heapq.heappush(a,0)
>>> heapq.heappop(a)
0
>>> while len(a) > 0:
... heapq.heappop(a)
...
2
3
9
>>>
If you want to copy a list, dic, set, use
.copy()
>>> a = [1,2,3]
>>> b = a #variable b and a reference to the same object [1,2,3]
>>> a.pop()
3
>>> print(a)
[1, 2]
>>> print(b)
[1, 2]
>>>
>>> b = a.copy() #give b a new list object, then fill the list with values 1 and 2
>>> a.pop() #original object changes, the copied object didn't change
2
>>> print(a)
[1]
>>> print(b)
[1, 2]
>>>
>>> a = set()
>>> b = a.copy() #copy a set
>>>
>>> a = {1:1, 2:2, 3:3}
>>> b = a.copy() #copy a dictionary
>>>
you can reverse a str or list
a[::-1]
>>> a = [1,2,3]
>>> b = a[::-1]
>>> print(a)
[1, 2, 3]
>>> print(b)
[3, 2, 1]
>>>
>>> a = 'abcd'
>>> print(a[::-1])
dcba
you can also get halves of a list/str, or a range of a list/str
>>> a = [1,2,3]
>>> b = a[1:] #from index 1 to end
>>> c = a[:1] #from start to index 1, not include index 1
>>> print(a)
[1, 2, 3]
>>> print(b)
[2, 3]
>>> print(c)
[1]
>>>
>>> a = 'abcd'
>>> b = a[1:]
>>> c = a[:1]
>>> print(a)
abcd
>>> print(b)
bcd
>>> print(c)
a
>>>
>>> print(a[1:2])
b
>>> print(a[1:3]) #from index 1 to 3, not include index 3
bc
>>>
to create an all 0, size n array:
[0]*n
to create an all 0, size mxn 2D matrix:
[[0 for _ in range(n)] for _ in range(m)]
don't use [0*n]*m !!!
we convert character to ascii value use ord(), convert ascii value to character use chr()
>>> ss = 'abcxyz'
>>> for ch in ss:
... ascii = ord(ch)
... print(ascii)
... print(ascii - ord('a'))
... print(chr(ascii))
...
97
0
a
98
1
b
99
2
c
120
23
x
121
24
y
122
25
z>>> ss = 'abcxyz'
>>> for ch in ss:
... ascii = ord(ch)
... print(ascii)
... print(ascii - ord('a'))
... print(chr(ascii))
...
97
0
a
98
1
b
99
2
c
120
23
x
121
24
y
122
25
z
python list is mutable, it can not be used as dictionary key, we need to turn it to tuple, the immutable version for dictionary key with tuple().
>>> a = [1,2,3]
>>> d = {}
>>> d[a] = 'xxx'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> aa = tuple(a)
>>> print(a)
[1, 2, 3]
>>> print(aa)
(1, 2, 3)
>>> d[aa] = 'xxx'
>>> print(d)
{(1, 2, 3): 'xxx'}
>>> d[(2,2)] = 'yy'
>>> print(d)
{(1, 2, 3): 'xxx', (2, 2): 'yy'}