begin-python

python小白入门

Posted by Mickey on December 13, 2017

一直觉得前端工程师不能完全拘泥于前端开发,应该多关注关注后端领域,毕竟作为http的两端,缺一不可,233333,正好公司后端用的语言是python,加之想学习python数据抓取配合前端进行数据可视化的开发,于是义无反顾的开始学习啦,本博客的内容来自《python核心编程》《廖雪峰python》,感谢🙏

人生苦短,我用python

下面列出一些python的知识点,总结一下,用来温故知新(本博客所用python版本为2.7)


1. python中 / 为浮点除,//为地板除, /只要有一个参数为浮点数,那么结果就是浮点数,//无论参数如何返回的都是整数 想要让/ 和 //分工明确,可以和引入,import division from __future__,这样/返回的都是浮点数,//返回的都是整数


2. python变量键入的写法和c有些相似

print "my name is %s" % baihao
print "my name is %s, my age is %d" % (baihao, age)

%r代表不管什么都打印出来 如果你使用了非ASCII字符而且碰到了编码错误,记得在最顶端加一行

#!/usr/bin/env python
# -*- coding: utf-8 -*-

第1行注释可以让这个hello.py文件直接在Unix/Linux/Mac上运行,第2行注释表示.py文件本身使用标准UTF-8编码
3. 打印多行字符串,用两个```包裹起来即可


4. python 中的list(列表)和 tuple(元组)list是可变的,tuple是不可变的,需要注意的是 a = (1) 这样a会被定义为1,一个元素的tuple写法为(1,)


5. python的列表也支持slice操作,取一个列表的前三个 L[0:3],tuple也是list,只是不可改变,tuple也可以使用切片


6. python字典的迭代,d = {‘a’: 1, ‘b’: 2, ‘c’: 3},for in 遍历的只是key,如果要遍历value for value in itervalues() ,两个都遍历的话 for k, v in iteritems()


7. 列表的迭代方法为for in,这样没法知道元素的索引,如果想要获取index的话,可以像下面这样

a = [1, 2, 3];
for k, v in enumerate(a):
  print k, v


8. python 中strip()等于js中trim()


9. map,reduce,filter,sorted都是高阶函数,区别是前三个的函数参数是第一个,sorted的函数参数是第二个


10. lambda 匿名函数,简化代码量


11. 在函数执行过程中动态增加功能的方式称为装饰器,decorator本质上也是高阶函数,接受需要动态添加功能的函数作为一个参数 初识装饰器

装饰器的数学定义其实就是 (g · f)(x) = g(f(x))

@deco2
@deco1
def func(arg1, arg2, ...): pass
func = deco2(deco1(func))


12. isinstance() < = > instanceof 同样用来判断类和引用类型(js中) type() < = > typeof 同样用来判断基本类型


13. python可以通过hasattr(obj, ‘attribute_name’), setattr(), getattr()来操作对象实例,有点类似DOM了,同样和字典一样,通过get()操作对象可能不存在,可以返回一个默认值


14. python作为一门动态语言,能够在程序运行过程中对类和实例对象绑定方法,贼强,这里需要从types里引入MethodType

Class.way = MethodType(way,None, Student) 类

instance.way = MethodType(way, instance, Student) 实例

from types import MethodType

class Stu(object):
	pass

def set_name(self, name):
	self.name = name

def set_age(self, age):
	self.age = age

Stu.set_name = MethodType(set_name, None, Stu) # 为class动态添加方法

bob = Stu()

bob.set_age = MethodType(set_age, bob, Stu) # 为实例动态添加方法


15. python类可以通过设置__slots__来限制类能被设置的属性,需要注意的是子类继承父类如果不定义__slots__属性的话,是没有限制的,子类如果定义了的话,它的可编辑属性为自己和父亲的slots中的值之和

class Stu(object):
	__slots__ = ('name', 'age')
	
>>> s = Student() # 创建新的实例
>>> s.name = 'Michael' # 绑定属性'name'
>>> s.age = 25 # 绑定属性'age'
>>> s.score = 99 # 绑定属性'score'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'score'


16. 通过set和get来操作类的属性有简写方法,通过python的装饰器

众所周知,python中,可以通过instance.property的方式直接访问属性,但是这样没法对新的数据做数值的判断,于是有了如下的装饰器(默认不能直接访问实例._property的内部属性,不然property毫无意义)

  class Student(object):
    @property
    def birth(self):
      return self._birth
    @birth.setter
    def birth(self, value):
      self._birth = value
    @property
    def age(self):
      return 2014 - self._birth

@property,@属性.setter,这样实例就能和操作属性一样操作方法了,s.birth,s.birth = ‘XXX’


17. python里面__XXX__这样命名的属性都是有hin大作用的,前面我们已经知道了__slots__

在python里面print 实例或者直接输出实例是 <__main__.Student object at 0x109afb310>,不好看,可以在class 里面定义__str__和__repr__,__str__定义print 返回的语句,__repr__定义在命令行直接输入显示的语句,偷懒的写法是__repr__ = __str__,这样只定义__str__就行了

__getattr__:当python在类属性中寻找不到的话,python解释器会自动调用__getattr__方法,我们可以在__getattr__中做一些限制

__call__: 实例初始化后,如果调用自身则访问该函数

class Student(object):
  pass
s = Student()
s() => 调用__call__方法

可以通过callable()方法来判断一个类是否包含__call__方法

可以通过__enter__和__close__来用with语句引用类的实例,__enter__在使用with语句时调用,会话管理器在代码块开始前调用,返回值与as后的参数绑定,__close__会话管理器在代码块执行完成好后调用,在with语句完成时,对象销毁之前调用

class Test(object):
    def __init__(self,name,flag):
        self.filename = name
        self.flag = flag
    
    def __enter__(self):
        '''
        @summary: 使用with语句是调用,会话管理器在代码块开始前调用,返回值与as后的参数绑定
        '''
        print "__enter__:Open %s"%self.filename
        self.f = open(self.filename,self.flag)
        return self.f
        
    def __exit__(self,Type, value, traceback):
        '''
        @summary: 会话管理器在代码块执行完成好后调用(不同于__del__)(必须是4个参数)
        '''
        print "__exit__:Close %s"%self.filename
        self.f.close()
        
    def __del__(self):
        print "__del__"
        
if __name__ == "__main__":
    with Test('test.txt','r+') as f:
        content = f.read()
        print content

    print "end"


>>> __enter__:Open test.txt
>>> Hello world!
>>> __exit__:Close test.txt
>>> del
>>>  end


18. 大多数编程语言都有用于捕获代码中发生的错误的方法,JavaScript中的try catch之类的,python也不例外,python中对应的代码为try except finally

try:
	res = 10 / 0;
	print res;
except BaseException, e:
	print e;
finally:
	print 'finally'

BaseException是所有异常的父类,python的错误捕获有类似冒泡的性质,比如main中调用了boo,boo调用了two,two函数中出现了错误,在main中依然能够捕捉到,另一个性质是,异常捕获有先后之分,如果在其他exception前调用了except BaseException,那么后面的补获语句将永远不会生效,这里给出python2.7的异常类间的继承关系,python异常类继承大全


19. 在python中I/O可以这样写

try:
	f = open('path/to/file', 'r');
	print f.read();
except:
	...
finally:
	f.close();

感觉十分的麻烦,于是python提供了with语句来简化IO的写法,比如上述代码可以简化为

with open('path/to/file', 'r') as f:
	print f.read();

with语句自然会调用close(),这样就不用在finally中手动调用close()来关闭文件流


20. python中对JSON的转换

在现在的web开发中,JSON应该是前后端通信的标准了233,python提供了非常完善的JSON处理方法,模块就叫做json

json.dumps()将python对象转为JSON对象

json.loads()将JSON对象转为python对象

当然,更多的时候,我们更愿意用class来表示一个对象,可以理解为MVC中的model层吧,这个时候,你要是直接用上面讲的方法,妥妥的给你报错,这时候,需要对dumps方法和loads方法配制一下

  def student2dict(std):
  	return {
     'name': std.name,
     'age': std.age,
     'score': std.score
  	};
  	
  json.dumps(s, default=student2dict)
  
  def dict2student(d):
  	return Student(d['name'], d['age'], d['score']);
  	
  json.loads(jsonobject, object_hook=dict2student)


21. 在python中有模块和包之分,模块的话就是一个简单的.py文件,包的话必须包含一个__init__.py文件,模块的引入方式为直接import,包的话,可以import全部的包,也可以from package import module


22. python由于GIL锁的原因,多线程不能使用多核,十分鸡肋,因而python多用多进程模型进行并发操作,一般来说使用的都是multiprocessing 包中的Pool来创建一个python进程池

from multiprocess import Pool

p = Pool()

task = p.apply_async(f,  args=(参数,))

p.close()
p.join()

result = task.get()

一般在p.close()之后调用get方法获取并发操作的返回值,避免阻塞


23. python List 向list末尾插入元素的方法是append方法,有一个简便的写法

a = [1, 2, 3]
a += 4,
a // [1, 2, 3, 4]


24. python scrapy中不能定义名字为model的模块,会有冲突,定义成models即可


25. python中str.find(substr)类似于js中的indexOf,然而,判断一个子字符串是否存在于父亲字符串中最快的方式为substr in str,list中的index()方法在字串不存在的时候会报错,不推荐使用


26. python内置函数zip的用法,zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。 如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表

a, b = [1, 2, 3], [4, 5, 6]
c = zip(a, b) # [(1, 4), (2, 5), (3, 6)]
d = zip(*c) [(1, 2, 3), (4, 5, 6)]

l是一个递增的数组快速请求最小的元素间隔
min_interval = min([abs(a - b) for a, b in zip(l, l[1:])])


26. python中的最小数和最大数,类似于java中的Interger.MAX_VALUE或者js中的Number.MAX_SAFE_INTEGER,float(‘inf’)(最大值),float(‘-inf’)(最小值)


27. python中sorted函数配合lambda的用法:

a = [[1, 2], [3, 4], [5, 6]]
sorted(a, key = lambda x: x[1]) # 按照数组的第二个元素的大小排序
sorted(a, key = lambda x: x[1], reverse = True) # 按照数组的第二个元素的大小的反序大小排序


28. python set 的操作

x, y = set(['a', 'p', 's', 'm']), set(['a', 'h', 'm'])

x & y = set('a', 'm') # 集合的交操作
x | y = set('a', 'p', 's', 'm', 'h') # 集合的并操作
x - y = set('p', 's') # 集合的差操作 


29. python 3 < 4 and 4 < 5 可以简写为 3 < 4 < 5,简直不要太优美


30. python函数是引用传值,修改传递的对象会影响形参


31. python对象的深浅拷贝

import copy

a = [1, 2, [3, 4]]
b = copy.copy(a) # 浅拷贝
c = copy.deepcopy(a) # 深拷贝


32. python中一行写不下的东西可以用反斜杠\分成多行来表示

 # check conditions
    if (weather_is_hot == 1) and \
    (shark_warnings == 0):
    	send_goto_beach_mesg_to_pager()


33. python合理的模块布局

#!/usr/bin/env python      起始行
"this is a test module"   模块文档
import sys, os            模块引入
debug = True              全局变量定义
class FooClass (object):  类定义
	pass
def test():               函数定义    
	foo = FooClass()
	if debug:
		print 'run test()'

if __name__ == '__main__': main方法
	test()


34. python中判断两个变量是否是一个对象的方法

obj1 is obj2 obj1和obj2是同一个对象

obj1 is not obj2 obj1和obj2不是同一个对象


35. 在python中,当一个对象生成的时候,python会给该对象绑上一个计算器,当该对象被引用的时候,计数器+1,当引用的对象销毁的时候,计数器-1,当计数器为0的时候,python垃圾回收器就回将该对象占用的内存释放,这就是python大概的内存管理机制


36. 在python中检测变量类型有两种方法 type() 和 isinstance(),在python2.2之后对类型和类的统一导致 isinstance()使用的越来越多,由于int既是类型也是类,使用isinstance(variable, [type1, type2])显得更为方便,如果要使用type()方法的话,可以按照如下进行一些优化

import types
type(a) == types.IntType # 这是最容易想到的

type(a) is types.IntType # 其实没必要去比较数值是否相同,这里可以调用is去判断是否为相同的对象

from types import IntType # 这样写可以避免每次使用IntType的时候都去types模块内查找


37. python中字符串和二进制串相互转换的方法

bin(int('256', 10)) # 0b100000000

str(int('0b100000000', 2)) # 256

''.join([bin(int(x)).replace('0b', '') for x in '999']) # 100110011001


38. python中ASCII和字符串的转换

ord('a') # 97
chr(97) # 'a'


39. python的随机数模块

from random import *
randrange(1, 5) # 返回1-5之内的随机一个整数,包括5
randint(1, 5) # 返回1-5之内的随机一个整数,不包括5
uniform(1, 5) # 返回1-5之内的随机一个浮点数
random() # 和js中的random一样,返回0-1之间的一个浮点数
choice() # 返回序列中的随机一个数值


40. python中遍历字符串,依次减少最后一个字符的输出,简便写法

s = 'abcde'
s[:None] = 'abcde' # 厉害了
for i in [None] + range(-1, -len(s), -1):
	print s[:i]
	
依次输出abcde, abcd, abc, ab, a


41. python中的string模块

import string
string.ascii_uppercase   # ABCDEDF...XYZ
string.ascii_lowercase   # abcdefg...xyz 
string.ascii_letters     # ABCD...XYZabcd...xyz
string.digits            # 0123456789
string.upper()           # 转为大写
string.lower()           # 转为小写


42. python字符串中一些内建函数

string.count(substr, begin, end) # 计算字符串中下表为begin到end的范围内,substr出现的次数,如果没有指定的话,即为0 - len(string)
string.startswith() # 检查字符串是否以XXX开始
string.endswith() # 检查字符串是否以XXX结束
string.replace(a, b) # 将字符串中的a替换成b
string.upper() # 将字符串替换为大写形式
string.lower() # 将字符串替换为小写形式


43. python不允许修改字符串中间的一个字符,如果需要修改的话,需要用切片创建一个新字符串

s = 'asd'
s[2] = 'S'
Trackback(innermost last):
File "<stdin>", line 1, in ? AttributeError: __setitem__

s = s[:2] + 'S' # asS


44. python可以用一个很方便的内建方法fromkeys()来创建一个“默认”字典,字典中的元素具有相同的值(如果没有给出,默认为None)

dict = {}.fromkeys(('x', 'y'), -1)
dict # {'x': -1, 'y': -1}


45. python中字典的大小比较比较鸡肋,因为python的字典为了查找的速度,key仅仅和hash值有关,但是还是记录一下python字典的比较方法

python字典比较首先进行字典长度的比较,然后是key值的比较,最后是value值的比较,比较规则和序列的一样,不做过多记录


46. python字典的内建函数

a = {'a': 1, 'b': 2}
a.get(key, default=None) # 获取字典中key的value,如果key不存在,则返回default值,如果没有给出default,则返回None
a.setdefault(key, default) # 获取字典中key的value,如果key不存在,则设置key的value为default并且放回该值,如果key存在的话,返回value值


47. python的不可变集合frosenset(存在hash,可以作为字典的key值)和可变集合set,set中的add类似list的append,set中的update类似list的extend

a = [1, 2]
a.extend('asd') # [1, 2, 'a', 's', 'd']
a.append('asd') # [1, 2, 'a', 's', 'd', 'asd']

a = set([1, 2])
a.add('asd') # set([1, 2, 'asd'])
a.update('asd') # set([1, 2, 'asd', 'a', 's', 'd'])


48. python中else语句的其他用法

在C语言中,你不会在条件语句范围外发现else语句,但python不同,你可以在while和for循环中使用else语句,在循环中使用时,else子句只在循环完成后执行,也就是说break语句也会跳过else块


49. python在使用for…in…迭代器遍历字典的时候,不能使用del语句删除字典中的项,因为一个序列的迭代器只是记录你当前到达第多少个元素,所以如果你在迭代的时候改变了元素,更新会立即反映到你所迭代的条目上,但是使用字典的keys()方法是可以的,因为keys()返回一个独立于字典的列表。而迭代器是与实际对象绑定在一起的,它将不会继续执行下去。


50. python使用生成器的一个例子

rows = [1, 2, 3, 17]

def cols():
	yield 56
	yield 2
	yield 1
	
x_product_pairs = ((i, j) for i in rows for j in cols())

for pair in x_product_pairs:
	print pair
	
(1, 56)...


51. python除了可以进行显示的参数调用,还可以传入列表和字典进行传参,传入字典的时候,可以不按照顺序,举个栗子:

def print_stu(name, age):
	print name, age

print_stu(*['bob', 21]) # bob, 21
print_stu(**{'name': 'bob', 'age': 21}) # bob, 21


52. python也可以在函数声明中定义接受可变数量的参数(我觉得js es6的三点运算符…就是和python学的2333)

def print_stu(name, *tuple, **obj):
	pass

print_stu('bob', 21, 32, arg1 = 'a', arg2 = 'b')
tuple = (21, 32)
obj = { 'arg1': 'a', 'arg2': 'b' }


53. python中局部作用域如果想影响全局作用域的变量,可以使用global关键字

is_this_global = 'xyz'
def foo():
	global is_this_global
	is_this_global = 'def'
	
>>> foo()
>>> print is_this_global
def


54. python中,推荐使用如下风格的import语句模块导入顺序

  1. Python 标准库模块
  2. Python 第三方模块
  3. 应用程序自定义模块

然后用一个空行分割这三类模块的导入语句,这将确保模块使用固定的习惯导入,有助于减少每个模块需要的import语句数目


55. python中,class中的__init__()方法和__del__()方法类似于构造函数和解构函数(可能有同学会说,__new__()才是构造函数,__new__()函数返回一个self实例,提供给__init__()初始化),需要注意的是,如果类存在一个继承的非object的基类,在__del__()中需要首先调用Parent.__del__(),下面给出一个最简单的__init__()__del__()的用法,记录该class实例化了多少个实例

class InstCc(object):
	count = 0
	def __init__(self):
		InstCc.count += 1
	def __del__(self):
		InstCc.count -= 1
	def howMany(self):
		return InstCc.count

a = InstCc()
b = InstCc()
b.howMany() 2
a.howMany() 2
del b
a.howMany() 1
del a
InstCc.count 0


56. python中类属性如果是不可变的,那么通过实例修改类属性不会对类属性造成影响,相当于在实例的__dict__属性中创建了一个新的字段,然而,如果通过实例修改的类属性是可变的话,比如字典,那么,修改实例属性会同步修改类属性,所以尽量不要通过实例修改类属性,操作类的静态数据的时候,使用Class.property


57. python中class存在静态方法(staticmethod)和类方法(classmethod),类方法定义的时候需要传入一个参数,一般是cls,可以理解为创建实例中的self,这个cls就代指类对象,可以通过cls获得类的属性,比如cls.name,下面给出一个栗子

  1 #!/usr/bin/env python
  2
  3 class Stu:
  4     count = 1
  5
  6     @staticmethod
  7     def how_many():
  8         print Stu.count
  9
 10     @classmethod
 11     def how_much(cls):
 12         print cls.count
 13
 14 if __name__ == '__main__':
 15     stu = Stu()
 16     stu.how_many()
 17     stu.how_much()


58. python类的继承,子类可以调用父亲类中的所有方法,但是如果在子类中需要覆盖掉父亲类的方法,例如__init__方法,可以在子类中显示的调用父亲类的方法

class P(object):
	def __init__(self):
		print "calling P's constructor"
		
class C(P):
	def __init__(self):
		P.__init__(self) / super(C, self).__init__() # 需要注意的是,super方法只有基类为新类才能有,如果基类为老类 class P: 这种类型的,只能用第一种方法显示的调用父亲类的重名方法

在类继承(super)的时候,存在方法解析顺序(mro),引入from pprint import pprint能够查看class __init__的时候调用栈,python会按mro的反序来调用


59. 类、实例的一些内建函数

issubclass(child, parent) python2.3之后parent可以为一个父亲类组成的元组

isinstance(example, class) 和issubclass一样,class可以为一个元组

*attr()系列函数可以在各种对象下工作,不限于类(class)和实例(instance),但是在类和实例里面,使用的非常多,于是在这里介绍一下

hasattr(obj, attr)

setattr(obj, attr)

getattr(obj, attr[, 默认值])

delattr(obj, attr)

vars(obj = None) 返回obj的属性及其的一个字典;如果没有给出obj,vars()显示局部名字空间字典(属性及其值),也就是locals()

在类中间方法中返回一个类,一般不建议直接使用类名,这样修改的时候需要逐个查找修改,推荐使用self.__class__方法


60. python except 捕获异常既可以分开操作,也可以作为一个元组合在一起捕获

try:
	A
except MyException: B
else: C(try块中的代码完全正确执行完毕没有发生异常调用else中的代码)
finally: D(无论如何都会调用的代码)

try:
	try-body
except TypeError, e:
	except-body
except ValueError, e:
	except-body

try:
	try-body
except (TypeError, ValueError), e:
	except-body


61. with语句的使用

python提供with语句进一步的透明程序中发生的细节,让程序员更加注重于代码的实现,用打开文件作为例子介绍一下with

with open('path', 'r') as f:
	for eachlines in f:
		# ...do stuff with eachLine or f...


62. python中,在windows环境下,换行符为’\r\n’,在mac环境下,换行符为’\n’,这在跨平台读取文件的时候,就会存在一些问题,解决方法如下所示:

  • 如果不是txt文件,建议用wb和rb来读写。通过二进制读写,不会有换行问题。
  • 如果需要明文内容,请用rU来读取(强烈推荐),即U通用换行模式(Universal new line mode)。该模式会把所有的换行符(\r \n \r\n)替换为\n。
  • os.linesep,可以获得当前操作系统的换行符
  • os.sep 用来分隔文件路径名的字符串
  • os.pathsep 用来分隔文件路径的字符串
  • os.curdir 当前工作目录的字符串名称
  • os.pardir 当前工作目录的父目录字符串的名称


63. python中,通过open或者file操作文件,当使用输入方法如read()或者readlines()从文件中读取行的时候,python并不会删除行结束符,同理,输出方法,write()或者writelines()也不会自动加入行结束符,这都是留给程序员自己解决的

f = open('myFile', 'r')
data = [line.strip() for line in f.readlines()]
f.close()


64. python中通过sys.argv属性提供了对命令行参数的访问,sys.argv是一个列表,sys.argc是一个number,也就是len(sys.argv)


65. python中关于正则表达式的操作

import re

pattern = re.compile(r'[abc]', re.S(.可以匹配\n)) 预编译增加速度

re.match(pattern, string) 从头开始匹配找到一个符合正则表达式的匹配串
re.search(pattern, string) 随便从什么地方匹配找到一个符合正则表达式的匹配串一般来说用search不用match
re.group() / re.group(0) 返回search或match
匹配到的串
re.group(1) 返回第一个字匹配
re.groups() 返回子匹配组成的元组
re.findall(pattern, string) 返回字符串中所有的匹配不限于找到第一个
re.sub(pattern, newstring, string) 类似于js中的replace
re.spilt(pattern, string) 分割字符串返回list速度比string的split快得多


66. python自定义类的一些方法自定义python类

__iter__: 如果一个类想被用于for … in循环,类似list或tuple那样,就必须实现一个__iter__()方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的next()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环

__getitem__: 要表现得像list那样按照下标取出元素

__getattr__: 当调用不存在的属性时,比如score,Python解释器会试图调用__getattr__(self, ‘score’)来尝试获得属性,这样,我们就有机会返回score的值

__call__: 直接调用实例() instance = Class() instance() => 访问 __call__()


67. 常用内建模块 – collections

  1. namedtuple: namedtuple是一个函数,它用来创建一个自定义的tuple对象,并且规定了tuple元素的个数,并可以用属性而不是索引来引用tuple的某个元素

     from collections import namedtuple
    	
     Point = namedtuple('Point', ['x', 'y'])
     p = Point(1, 2)
     p.x // 1
     p.y // 2
    

    尽管namedtuple在很多场合都非常有用,但是在某些场合中,使用namedtuple反而不好

    • namedtuple无法设置默认值
    • namedtuple可以通过下标和key来读取,可能导致其他人以不符合设计者意图的方式使用这些元组
  2. deque: 使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈

     >>> from collections import deque
     >>> q = deque(['a', 'b', 'c'])
     >>> q.append('x')
     >>> q.appendleft('y')
     >>> q
     deque(['y', 'a', 'b', 'c', 'x'])
    
  3. OrderedDict: 字典的key值排序是按照hash来的,如果想按照插入的顺序来排序,可以采用OrderedDict

     >>> from collections import OrderedDict
     >>> d = dict([('a', 1), ('b', 2), ('c', 3)])
     >>> d # dict的Key是无序的
     {'a': 1, 'c': 3, 'b': 2}
     >>> od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
     >>> od # OrderedDict的Key是有序的
     OrderedDict([('a', 1), ('b', 2), ('c', 3)])
    
  4. Counter: Counter是一个简单的计数器,例如,统计字符出现的个数

     >>> from collections import Counter
     >>> a = Counter('programmer')
     Counter({'r': 3, 'm': 2, 'a': 1, 'e': 1, 'g': 1, 'o': 1, 'p': 1})
     >>> a.most_common(2)
     [('r', 3), ('m', 2)]
    
  5. defaultdict(function, init_dict): 允许使用者提供一个函数,以后在查询本字典的时候,如果里面没有待查的key,那就用这个函数为该键创建新值

     >>> from collections import defaultdict
     >>> a = defaultdict(int)
     >>> a['a'] += 1
     >>> a['a'] # 1
     >>> a = defaultdict(str)
     >>> a['a'] += 'a'
     >>> a['a'] # 'a'
    


68. 常用内建模块 – base64

  • base64.b64encode()
  • base64.b64decode()

由于标准的Base64编码后可能出现字符+和/,在URL中就不能直接作为参数,所以又有一种”url safe”的base64编码,其实就是把字符+和/分别变成-和_

  • base64.urlsafe_b64encode()
  • base64.urlsafe_b64decode()


69. 常用内建模块 – hashlib

其实就是 MD5, SHA1 之类的加密算法

import hashlib

md5 = hashlib.md5()
md5.update('how to use md5 in ')
md5.update('python hashlib?')

sha1 = hashlib.sha1()
sha1.update('how to use sha1 in ')
sha1.update('python hashlib?')


70. python中快速建立集合的方法,{()}这样就建立了一个集合


71. python sqlalchemy 的常用API

sqlalchemy的API

  • query(Table) 查询
  • one() 返回一个确定的item,如果返回多个会报错,没有返回也会报错
  • first() 返回当前查询排行第一的结果,如果没有实体则返回None
  • order_by(Table.Field) 按照一个字段的数值从小到大的返回list
  • order_by(Table.Field.desc()) 反序
  • filter(Table.Field == num) 过滤函数,相当于sql中的where
  • from sqlalchemy.sql import func, func中有max,min,count等函数,可以用于查询,query(func.max(Table.Field))
  • scalar() 返回第一个元素的第一个结果(这就是和first的区别),如果没有行存在,返回None。如果返回多行,则引发MultipleResultsFound,session.query(Item.id, Item.name).scalar() == 1,只返回id,经常和func共同使用
  • limit(int) 和sql中的limit的用法一样,最多返回limit()参数的记录
  • offset(int) 从int索引开始返回
  • slice(head, tail)和前端的slice一样的用法,返回索引从head到tail-1的记录


72. python中的堆排序heapq模块

heapq模块实现了python中的堆排序,并提供了有关方法。让用Python实现堆排序有了简单快捷的方式。

heapq官方文档

  • 实现堆排序

      #!/usr/bin/env python
      # -*- coding: utf-8 -*-
    	
      from heapq import *
    	
      def heapsort(iterable):
          h = []
          for value in iterable:
              heappush(h, value)
          return [heappop(h) for i in range(len(h))]
    	
      if __name__ == '__main__':
          print heapsort([1, 3, 5, 9, 2])
    
  • heappush(heap, item)

    将item压入堆数组

  • heappop(heap)

    返回heap堆中当前的最小元素

  • heappushpop(heap, item)

    先将item压入堆数组,然后再返回heap堆中当前的最小元素

  • heapreplace(heap, item)

    先返回heap堆中当前的最小元素,再将item压入堆数组

  • heapify(arr)

    arr必须是list,此函数将list变成堆,实时操作。从而能在任何情况下使用堆的函数。

      >>> a = [1, 5, 3]
      >>> heapify(a)
      >>> heappop(a)
      1
      >>> b = [4, 2, 5]
      >>> heappop(b) # 因为不是heap堆数组
      4
    
  • merge(*iterables)

      >>> a = [1, 3, 5]
      >>> b = [2, 4, 6]
      >>> c = merge(a, b) # 生成一个generator
      >>> list(c)
      [1, 2, 3, 4, 5, 5]
    
  • nlargest(n, iterable[, key]),nsmallest(n, iterable[, key]),获取列表中最大、最小的几个值。与sorted(iterable, key=key, reverse=True)[:n]等价

      >>> a
      [2, 4, 6]
      >>> nlargest(2, a)
      [6, 4]
    


73. python中的all函数

all(iterable),如果iterable中的所有元素不为0,’‘,False或者iterable为空,返回True,反之。返回False


74. python中random模块的randint和randrange的区别

randrange([start,] stop [, step]):从start到stop中,以step为间隔中随机取一个整数,可以理解为choice(range(start, stop, step)

randint(start, stop):从start到stop(包括stop)中随机获取一个数字,相当于randrange(start, stop + 1)


75. python的bisect模块,可以用于二分查找,存在以下6种方法

  • 实现二分查找

      from bisect import *
    
      def binary_search(iter, target):
          index = bisect_left(iter, target)
          if index != len(iter) and iter[index] == target:
              return index
          else:
              return -1	
    
  • insort(arr, target),将target插入arr数组

      arr = [1, 2, 4]
      insort(arr, 3)
      print arr # [1, 2, 3, 4]
    
  • insort_left(arr, target)以及insort_right(arr, target),这两个函数分别从左右两个方向进行插入,多用于插入数组中已经存在的数值

  • bisect(arr, target),返回target应该插入arr的位置,但是不插入

      arr = [1, 2, 4]
      print bisect(arr, 3) # 2
    
  • bisect_left(arr, target)以及bisect_right(arr, target),这两个函数类似于insort_left和insort_right,只返回索引,但是不插入


74. python中[[False] * 3] * 3创建的2维数组,其实每一行指向的内存地址是一样,可以通过id()查看内存, 通过索引修改一个位置的元素,会将一列全部修改,可以通过[[False] * 3 for i in xrange(3)]来创建不同的

arr = [[False] * 3] * 3
arr1 = [[False] * 3 for i in xrange(3)]
arr[0] is arr[1] # True
arr1[0] is arr1[1] # False


75. python2.6新增了一种格式化字符串函数format()

"{0} {1}".format("hello", "world") # hello world
"{str1} {str2}".format(str1 = 'hello', str2 = 'world') # hello world
obj = {'str1': 'hello', 'str2': 'world'}
"{str1} {str2}".format(**obj) # hello world


76. python中十进制和二进制、八进制、十六进制的相互转换

  • 十进制转二、八、十六进制

      a = 10
      bin(a) # '0b1010'
      oct(a) # '012'
      hex(a) # '0xa' 
    
  • 二、八、十六进制转十进制

      int('1010', 2) # 10
      int('12', 8) # 10
      int('a', 16) # 10
    


76. python的lambda函数也会出现js中的函数陷阱

func_list = []

def func(i):
    return i

for i in xrange(10):
    func_list.append(lambda :func(i))

for fun in func_list:
    print fun()

上述代码会打出10个9,如果想要正确显示,需要这样写func_list.append(lambda j=i: func(j))