Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Python3 Cheatsheet

Download as pdf or txt
Download as pdf or txt
You are on page 1of 6

Detailed explanation is available at

Python3 Cheatsheet Sorting HOW TO - Python 3.8.5 documentation


Python lists have a built-in method that modifies the list in-place. There is also a built-in
Useful Build-in Functions function that builds a…
1. zip docs.python.org

A quick show of what it can do:


3. any
a = (“John”, “Charles”)

Refer to https://www.programiz.com/python-programming/methods/built-in/any:
b = (“Jenny”, “Christy”)
The any() function returns True if any element of an iterable is True. If not, any() returns
x = zip(a, b)
False.
#use the tuple() function to display a readable version of the result:

>>> any([0,1])

print(tuple(x)) #print ((‘John’, ‘Jenny’), (‘Charles’, ‘Christy’))


True

#since 1 is True

Detailed explanation is available at >>> any([1,0])

True

https://www.w3schools.com/python/ref_func_zip.asp
#since 1 is True

>>> any([0,None])

2. sorted False

#since not element is True


This is useful to sort any collection(list, dictionary). A simple example looks like:

4. enumerate()
>>> sorted([5, 2, 3, 1, 4])

[1, 2, 3, 4, 5] This function is pretty handy when I want to get both index and value for a list (or key
and value for a dict).

In addition, there is an optional parameter “key” which serves as a function that can
take one input (it will be one element of the collection) and return whatever you want names = ['ant', 'maven', 'gradle']

versions = ['1.0', '2.0', '3.0']


for sorting purpose. Certainly, I can put a lambda expression there. An example looks
like: for i, v in enumerate(names):

full_name = v + '-' + versions[i]

print(full_name)
>>> sorted([5, 2, 3, 1, 4], key=lambda x:-x)

[5, 4, 3, 2, 1]

'''

#when 5 is used to compare, I actaully make it -5 so it will be the


Output:

smallest number and hence it will be the first one.


ant-1.0

maven-2.0

gradle-3.0

'''
Lambda Expression
In addition, I can add an optional parameter which specifies the starting index, an Lambda expression is actaully an anonymous function. It’s pretty handy when I need a

example from https://book.pythontips.com/en/latest/enumerate.html looks like: small function (one line of code) while I don’t want to take the trouble to write a
formal one.

my_list = ['apple', 'banana', 'grapes', 'pear']


Assume I want a function that can return the value of the input integer minus 2 if input
counter_list = list(enumerate(my_list, 1))
is positive, I can write:
print(counter_list)

# Output: [(1, 'apple'), (2, 'banana'), (3, 'grapes'), (4, 'pear')]

def decreaseByTwo(x):

return x-2 if x > 0 else x


5, initilize a multidimensional array
x = decreaseByTwo(x)
a) To get a one dimension array with all 0, below both ways will do:

While using lambda expression, it will be


>>> f = [ 0 for _ in range(2) ]

>>> f

[0, 0]
decreaseByTwo = lambda x: x-2 if x > 0 else x

x = decreaseByTwo(x)

OR
Lambda expression can be very useful wherever a function is needed to be a input
parameter.
>>> f = [ 0 ] * 2

>>> f

[0, 0] Detailed explanation is available at

https://www.w3schools.com/python/python_lambda.asp
But per this link, careful — the second technique doesn’t generalize to
multidimensional arrays or lists of lists. Which leads to the List of lists changes Nested Function
reflected across sublists unexpectedly problem. Nested function is a function inside a function. It’s handy when you need to reuse a
batch of codes but that reuse only make sense to your current function. At that
b) to get a multidimensional array moment, you can create a nested function inside your current function.

This is an example of a nested function. Inside parent(), a nested function child() is


>>> f = [ [0 for _ in range(2) ] for _ in range(2)]

>>> f

defined and can be invoked after its definition (but still inside parent()).
[[0, 0], [0, 0]]

>>> f[0][0]=3
Introducing nonlocal
>>> f

The function child() can read or assign a variable‘s value like


[[3, 0], [0, 0]]
One possible confusing part is what if I want to change an outside dict/list/other
def parent():

a = 3
objects inside a nest function, do I need to claim “nonlocal” first? The answer is not
b = 9 since, like child() in below example shows, changing part of variable a is not a new
def child():
assignment; but in child2(), I use “nonlocal” to completely change outside a instead of
print(a) #will print 3
partially.
print(b) #will print 9

child()
def parent():

a = {'parent':3}

However, there is a situation that child() may want to change the value of a variable def child():

that is defined in parent() like below. a['child'] = 2

print(a)

def child2():

def parent():
nonlocal a

a = 3 a = {1:2}

print(a) #will print {1:2}


def child():

print(a) #will print 3


print(a) #will print {'parent':3}

a = 5
child()

print(a) # will print 5


print(a) #will print {'parent':3, 'child': 2}


child2()

child()
print(a) #will print {1:2}

print(a) #will still print 3 although in child() it's set to 5 child()

print(a) #will print {1:2, 'child': 2}

However, in above example, when a=5 is called, Python3 actually creates a local (only
valid within child()) variable which is also named ‘a’ and shadows the external a in Collections
following executions within child(). But outside child(), a will still refer to outside one. There are quite a lot of useful classes inside Python3 collection module. Per official
doc, collections module
To ensure the ‘a’ inside child() using the outside one, I need to put “nonlocal” as
below. implements specialized container datatypes providing alternatives to Python’s general
purpose built-in containers, dict , list , set , and tuple .

def parent():
What does that mean? Let me use 2 examples to explain:
a = 3
1. defaultdict
def child():

print(a) #will print 3


Note: the first letter is in lowercase.
nonlocal a

a = 5

print(a) # will print 5


Assume I need to have a hashmap to count how many times a letter appears in a string.

I can write below code.
child()

print(a) #will print 5 since in child() it's set to 5


It’s easy to add a key/value pair, just
s = '123ab'

m = {}

for c in s:
a[(1,2)]=(3,4)
if m.get(c) == None: #because c may not be an existing key in m

m[c] = 0 #I need to initialize it first to avoid exception

And easy to remove a pair


m[c] += 1

del a[(1,2)]
However, it’s a little bit clumsy. Let me show the defaultdict version:
For time complexity, adding or removing and accessing are all O(1) operations.

Iteration of dict elements:


from collections import defaultdict

s = '123ab'

m = defaultdict(int)
d = {'parent':3, 'child': 4}
for c in s:

#if c is not yet a valid key, m[c]=0 will be called first


#access keys and then use key to access value

m[c] += 1 for key in d:

print(key, d[key]) #each time a key/value pair of d is printed

2. Counter #access key/value

for key, value in d.items():

For the example of generating a hashmap to count how many times a letter appears in print(key, value) #each time a key/value pair of d is printed
a string, there is actually another more easy way as below.
#Typical incorrect ways to access key/value

for key, value in d:

print(key, value)

from collections import Counter


for key, value in enumerate(d):

s = '123ab'
print(key, value)
counter_s = Counter(s)

counter_s # print Counter({'1': 1, '2': 1, '3': 1, 'a': 1, 'b': 1})

counter_s['z'] #print 0 since there is no 'z' key


2. Tuple
According to Python — Tuples — Tutorialspoint:
Since Counter is a subclass of dict , I can easily use it to access each key and its value.
A tuple is a collection of objects which ordered and immutable. Tuples are sequences, just

Useful Data Structures like lists. The differences between tuples and lists are, the tuples cannot be changed unlike
lists and tuples use parentheses, whereas lists use square brackets.
1. Hashmap/Dictionary
In Python 3, a dict actually performs like a hashmap. A dict is composed of multiple Tuple is very handy whenI need to just group a series of objects, for example, I can use
key/value pairs in the format of key:value, a comman(,) is used to separate each pair. a (x,y) tuples to represent a two dimension point while (x,y,z) to a three dimension
The dict can be initilized like point. It looks very logically and elegant.

a={1:2,’strKey’:’strValue’} As mentioned above, a tuple is immutable which means it can not be changed once
defined. Look at below example:
Any hashable type can be key. Please note that list (like [1,2,3,4]) and dict (like {‘1’:2})
are not hashabel.
contains smallest value. So Python’s heapq is actually min heap which means on the
a = (1,0)

print(a[0]) #this will print 1


top of the heap is always the smallest element.
a[0] = 2 #this will throw an error
Another fact is that an element can be a integer as well as a basic data structure like
tuple. Actually, whatever data structure (like string) I can put inside a list can be an
3. List/Stack
element’s type in heap. That’s why it can be used as Priority Queue as below example
A list is a collection of objects which are NOT immutable. Please compare below codes
illustrates:
to the codes in above tuple section and note that square brackets ‘[]’ are used here in
list definition while parentheses ‘()’ are used in tuple definition.
>>> from heapq import *

>>> h = []

a = [1,0]
>>> heappush(h, (5, 'write code'))

print(a[0]) #this will print 1


>>> heappush(h, (7, 'release product'))

a[0] = 2
>>> heappush(h, (1, 'write spec'))

print(a[0]) #this will print 2 >>> heappush(h, (3, 'create tests'))

>>> heappop(h)

(1, 'write spec')

Very often, list in Python3 is used as a stack. Data can be pushed to a stack or popped
up. The only magic here is the first pushed data will be the last one to pop up (often A heap queue can be initialized in 2 ways:
referred as “first in last out” FILO). The next to-be-popped data stays at the top of
stack. Normally a peek function is expected to take a look at the data at the top of stack 1. use a empty list (see above example)
without actually popping it up. Look at this example to get more understanding:
2. use heapq.heapify(list)

s = []

>>> from heapq import *

s.append(1) #here I use append to serve as push

>>> h = [(5, 'write code'),(1, 'write spec')]

print(s) #this will print [1]

>>> heapify(h)

s.append(2) #now s becomes [1,2]

>>> heappop(h)

s.append(3) #now s becomes [1,2,3]

(1, 'write spec')

a = s.pop()

>>> heappop(h)

print(a) # it will print 3, which last in but first out

(5, 'write code')


print(s) # since 3 is popped, s is [1,2]

s.append(3) #now s becomes [1,2,3] again

print(s[-1]) # print 3, s[-1] is equal to peek

print(s) # print [1,2,3], peek(unlike pop) will not change a stack Pleaes note that each time heappush/heappop is called (when a new element is added
or removed), the heap is adjusted internally to againt ensure itself a min heap
4, Heap Queue (therefore, each element is equal to or less than its children, and smallest one on the

Please note that this is a summary and extention with example of official document top).

https://docs.python.org/3/library/heapq.html.
There are 2 very useful functions in heapq:
Within Python’s heapq, all elements are placed in a binary tree where any element’s
heapq.nlargest(n, iterable, key=None)
value will be less than or equal to any of its children. Not surprisely, the root of the tree
heapq.nsmallest(n, iterable, key=None)
where key is a function of one argument that is used to extract a comparison key from
head = ListNode()

each element in iterable. An example looks like below. preNode = head

...

preNode.next =

preNode = curNode

>>> from heapq import *


...

>>> h = [(1,4),(2,3)]
return head.next
>>> heapify(h)

>>> nsmallest(2,a,key=lambda p:p[1])

[(2, 3), (1, 4)]

>>> nsmallest(2,a)
To connect this technique to real world examples, I attach 2 practices of it as below.
[(1, 4), (2, 3)]

Major heapq operations (heapify, heappush, heappop) has O(N) time complexity while
some (nsmallest, nlargest) has O(1).

Some Leetcode problems (which aim to find top K smallest/largest elements) can be
easily solved by using heap:

5. Dummy head of Linked List


In many cases, if I want to append a node to a linked list(which may not exist), I need
to have an if/else like:

head = None

...

if head == None:

header = ListNode()

else:

preNode.next = ListNode()

preNode = curNode

...

return head

The reason is preNode can be None if the linked list does not yet exist. To make above
code more concise and beautiful, there is a technique called dummy head: I don’t
create the linked list when needed, instead, I will just go ahead and create the head
and have preNode pointing to it so that preNode is always valid. Accordingly, I should
remember the real data starts on head.next instead of head since the head is just a
dummy placeholder. Compare below code snippet with the previous one to get a
understanding of that.

You might also like