programming_language
Selected from Introduciton to Python, authored by Bill Lubanovic
This is the best Python Tutorial that I have ever read.
Python is strongly typed.
Variables are just names.
Assignment just attaches a name to the object.
/
carries out floating-point (decimal) division.
//
for integer division.
An "int" can be any size.
Python handles humungous integers with no problem.
Convert a string containing characters that would be a valid float.
float('99')
would be 99.0
Strings in Python are immutable.
Duplicate a string with *
, such as 'str'*3
Slice with [start: end: step].
Reverse with 'string'[::-1]
= 'gnirts'
Combine with join(), the opposite of split().
'string'.startswith('sub')
and
'string'.endswith('sub')
return boolean.
Find the offset of the first occurrence of the word.
'string'.find('i')
Find the last
'string'.rfind('i')
Count
'string'.count('i')
Removing sth from both sides
strip('sth')
Deal with word cases:
capitalize()
title()
upper()
lower()
swapcase()
Deal with alignment within the specific number(like 30) of spaces:
center(30)
ljust(30)
rjust(30)
Combine lists with extend()
or +=
Add an item by offset with insert(offset, item)
Delete an item with del
.
del mylist[2]
del
is a Python statement: it detaches a name from a Python object and free up the object's memory if that name is the last reference to it.
Delete an item by value with remove(value)
pop(offset)
Get an item by offset and delete it at the same time.
pop()
pops the last item.
Find the offset of an item by value with index()
mylist.index(item)
Sorting in default ascending order.
mylist.sort()
sorts the list itself.
general function sorted()
sorts the copy.
Assign with =, Copy with copy()
Three ways to copy:
The list `copy()` function
The `list()` construction function
The list slicing `[:]`
Tuples let you assign multiple variables at once. (tuple unpacking)
Exchange variables in one statement. a, b = b, a
Goodness of Tuples versus Lists:
1. Tuples use less space.
2. cannot clobber tuple items by mistake.
3. can use tuples as dictionary keys
4. Named Tuples can be a simple alternative to objects.
5. Function arguments are passed as tuples.
use dict()
to convert two-value sequence into a dictionary.
dict([['a',1], ['b',2]])
to make {'a':1, 'b':2}
Combine dictionaries with update()
. The value from the second dictionary wins when deplication.
Delete an item by key with del
.
Delete all item using clear()
.
Test a key using in
key1 in mydict
returns boolean.
Non-thrown item access using get(key, optional_value)
If the key does not exist, the optional value will be returned. If no optional value provided, return None.
Get all keys using keys()
Get all values using values()
Get all key-value pairs using items()
Set Operations:
&
|
-
^
Set Simbols:
< proper subset, returns boolean
> proper superset
>= or issuperset()
Python lets you do this.
10 < x < 15
Python considers all these false
:
False, None, 0, 0.0, '', [], (), {}, set()
Check break use with else after a while
while cond_satisfied:
do_sth
if cond_hit:
break # jump out of the loop in condiction
else:
print('No break') # execute if break not called
This is the same with "for" loop.
Iterating multiple sequences in parallel with zip()
.
zip()
stops when the shortest sequence is done.
It returns an iterable object.
Generate number sequences with range(start, stop, step)
A comprehension is a compact way of creating a Python data structure from one or more iterators.
Tuples do not have comprehensions!
(expression for expression in iterable)
returns a generator comprehension.
You cannot restart or back up a generator.
None is a Python value that holds a place when nothing to say.
To detect a None, use if thing is None
.
specify arguments by the names of their corresponding parameters.
Default values are calculated when the function is defined.
Gather positional argument with *
An asterisk groups a variable number of positional arguments into a tuple of parameter values.
def f(*args):
pass
f(1,2,3,4) # args is (1,2,3,4)
Gather keyword arguments with **
group keyword arguments into a dictionary.
def f():
'this is the docstring of this function'
pass
# to get the docstring
help(f)
print(f.__doc__)
Python Functions are the first class citizen.
function.__name__
returns the function name.
The main program is assigned the special name __main__
.
So the codes below are commonly-seen.
if __name__ == "__main__":
main()
A global value can be accessed inside a function but cannot be changed.
To change it, keyword "global" is needed.
x = 1
def f():
global x
x = 2 # x can be changed
locals()
/globals()
returns a dictionary of the contents of the local/global namespace.
try:
sth.
except IndexError as er:
do_sth
except Exception as others:
do_sth_else
A module is a Python file.
from module import
function_name or class_name
import module
module.function()
A package is a file hierachy of organized files.
In the source directory of a package, a file named __init__.py
is needed to denote the whole directory as a Python package.
Handling missing keys
dictionary.setdefault(key, value)
set if not get.
Default keys
from collections import defaultdict
defaultdict()
takes a function as argument. It specifies the default value of any new key.
such as defaultdict(list())
Counting items
from collections import Counter
Counter
takes a list as input
Methods:
most_common(30)
combine two counters using +
OrderDict()
Iterating over data structures
import itertools
itertools.chain([1,2], [3,4])
iterate as a whole
cycle([1,2,3])
infinite
accumulate()
iterate with cumulative results
accumulate([1,2,3], multiply)
do multplication now. (Simply like C++ template)
Nicely print with pprint()
super
Once the __init__
function is defined in the sub-class, it overrides the initialization function in the parent class which will not be called automatically anymore.
So the sub-class should call its parant with super.__init__(param)
The first argument of class method must be self
Python attributes and methods are all public.
You need to make it private in a Pythonic way.
class HideYourName():
def __init__(self, name):
self.hidden_name = name
def getter(self):
return self.hidden_name
def setter(self, new_name):
self.hidden_name = new_name
# define two methods as properties of attribute "name"
name = property(getter, setter)
In this case, users call with HideYourName('Bob').name
as a normal attribute. (But the get/set details are re-defined and the true value 'hidden_name' is hidden but still can be called)
Another way to define properties is to use decorators
@property
def name(self):
return self.hidden_name
@name.setter
def name(self, new_name):
self.hidden_name = new_name
Call as usual.
A property can refer to a computational value.
@property
def diameter(self):
return 2 * self.radius
Call it as c.diameter
The advantage of using properties over direct attribute access: only fix the codes within class if definition of the attribute changed.
A naming convention for attributes that should not be visible outside of the class definition: begin with two underscores.
def __init__(self, name):
self.__hidden = name
You cannot access the hidden attribute with c.__hidden
now.
However, this privacy is done by Python with mangling and is not secure at all.
c._ClassName__hidden
cross over the getter to visit the private value.
instance methods
are normal methods begined with self
class methods
affect the class as a whole. Any change made to the class affects all its objects.
Denote with @classmethod
The first parameter to a class method is the class itself, denoted as cls
as tradition.
A class method accesses a class attribute.
class C():
cnt = 0
def __init__(self):
C.cnt += 1 # refer to a class attribute
@classmethod
def count(cls): # the class itself
return cls.cnt
@staticmethod
self
or class
method.
@staticmethod
def info():
print('hello')
A loose implementation of polymorphism - apply the same operation to different objects even if they are different classes.
def who_says(obj):
print(obj.who(), 'says', obj.says())
Any object with these two methods can be called by the function.
__eq__(self, other) # equal
__ne__(self, other) # not equal
__lt__(self, other) # less than
__gt__(self, other) # greater than
__le__(self, other) # less or equal
__ge__(self, other) # greater or equal
__add__(self, other)
__sub__(self, other)
__mul__(self, other)
__floordiv__(self, other)
__truediv__(self, other)
__mod__(self, other)
__pow__(self, other)
__str__(self) # convert the object into a str used by print()
__repr__(self) # used by interpreter echoing
__len__(self)
Avoid overengineering data structures.
Named tuples are better than objects.
Immutable, time-efficient, access with dot-notation/names, used as dictionary key
from collection import namedtuple
Duck = namedtuple('key1', 'key2')
duck = Duck('value1', 'value2')
duck.key1 # access with dot-notation
duck.key2