Effective Python
How to modify your Python code style, and use it in a more effective way, this post will introduce the pythonic code style to you.
####Language sugar and suggested code style
-
slice
You may see [::-1] in python, you also may see [begin:end], which is a brief edition of [begin:end:step]. [begin:end] is suggested, and [begin:end:step] often causes unexpected bugs, for example, it will break for Unicode characters -
str.format()
In C++ ect., %s is used to express a string, it works for python, but the suggested way to express string in python is:
value={'greet':'Hello world','language':'Python'}
print '%(greet)s from %(language)s.' % value
#or
print '{greet} from {language}.'.format(greet='Hello world',language='Python')
- join
''.join(['str1','str2']) #instead of using str1+str2.
- with
To close a file immediately, use ‘with’ to operate the file.
with open('files/tex.txt') as f:
f.write('first line')
- zip The zip() built-in function can be used to iterate over multiple iterators in parallel. And in Python 2, zip returns the full result as a list of tuples.
x=[1,2,3]
y=[4,5,6,7]
zip(x,y) #[(1,4),(2,5),(3,6)]
-
assert
use assert expression1,expression2 to capture the constraint defined by the user. -
deepcopy
Distinguish shallow copy from deep copy and ‘=’
#= reference
import copy
copy.copy(object)#shallow copy, one time of coping
copy.deepcopy(object)#deep copy, copy objects iteratively
- map & filter
usemap( func, seq1[, seq2...] )
to call a function and return a list of the results, which is equal to[f(x) for x in iterable]
.
#first situation: map(func,iterable) where func only has one para
#second situation: map(func,iterable1,iterable2) where func(para1,para2) and first elem of iteable1 and iterable2 are used as para1 and para2.
#if the func is none, map() is equal to zip()
#all constraint to: length of return is equal to length of iterable
- List comprehensions
When programming, frequently we want to transform one type of data into another. With the help of list comprehensions we can do it more effectively.
nums = [0, 1, 2, 3, 4]
even_squares = [x ** 2 for x in nums if x % 2 == 0]
print even_squares # Prints "[0, 4, 16]"
# filter
x = filter(lambda x:x>1,range(-10,10))
>>>[2, 3, 4, 5, 6, 7, 8, 9]
-
Concurrency & Parallelism
To make full use of the CPU resource of computer. Concurrent(Thread) program may run thousands of separate paths of execution simultaneously. In contrast, the time parallelism(Process) takes to do the total work is cut in half.
In python, The existence of GIL(Global Interpreter Lock) means your program could utilize only one thread at the same time.
I/O-bound:UseThreading
(false parallelism) for blocking I/O, which may take more time to execute the CPU-bound program. Also useLock
class in theThreading
to avoid data races which may not be avoid by GIL. CPU-bound:UseMultiprocessing
-
*args and **kwargs
Indef(arg, *args, **kwargs)
,*args
means all the default value of arguments, and**kwargs
means all the default key-value arguments. Inside of a function, we use args and kwargs(without *) to call the value passed to this function. -
docstring
Use docstring(Triple double-quoted strings) to describe your function and class.
def load_data(f, arg):
"""
:param f:first argument
:param arg: another argument
:return:{item_key(header of excel/csv):item_value}
"""
- Generators
Generator is a kind of Iterator(which has next or __next__ def), However, during the iteration, the result of return will be created when they are called instead of storing them all in memory.
def generator_func():
for item in range(10):
yield item
# fist way to call
gen = generator_func()
next(gen) # for iterable such as str, use iter() instead of next() for itertor
# second way to call
for item in generator_func():
print item
Reference
- Brett Slatkin Effective Python.
- Y.Zhang, Yh.Lai Writing Solid Python Code.