python学习

2017/04/02 python

1、基础知识

1.1 常用安装命令

pip list           #在commond中。查看已经安装的包。
pip install ****.whl    #pip是自带程序,需要设置环境变量。以后就可以从网站下载*.whl格式的扩展包了。使用这个命令安装。
pip uninstall ***       #卸载某包

pip install **     #一般安装用这个就行。

#有时候上面命令会下载超时,使用下面这个命令,指定从douban下载
pip install ** -i https://pypi.douban.com/simple 

#在mac中自带python2.7,有时候需要更新包,由于maxos采用了更高级的内核保护机制,会发生错误。就用这个命令。
sudo pip install numpy --upgrade --ignore-installed 

#有时候有些包用pip会出错,用conda。
conda install **  

2. Python数据结构

2.1 元组tuple

Python中的元组一旦创建了,不能以任何方式改变。元组和字符串序列都是不可变序列。

  • 定义元组tuple用圆括号()
    a=(1,2,3,'44','555')
    
  • 元组索引,从0开始,元组内元素有确定的顺序
a[0]
a[-1]    #负的索引,从尾部开始计数
a[1:6]   #对元组切片操作,切片得到新的元组
  • 元组遍历
for b in a:
    print b

for i in range(0,len(a)):
    print a[i]

2.2 列表list

列表是Python中最常用的数据结构,它是可变的序列。

  • 定义列表用方括号[]
a=[1,2,3,'44','555']
  • 列表的内置函数
a.append(3)
a.insert(3,900)  #下标3处,插入900
a.extend([7,9])  #合并两个list
a.index(100)  #搜索,找不到会爆异常
a.remove(3)  #删除一个值,首次出现
a.pop()   #删除最后一个元素

2.3 集合set

  • 定义集合用花括号{},或者内置函数
    s={3,5,7,8}
    s=set(alist)
    

    2.4 字典dict

根据两个list构造字典

keys = ['a', 'b', 'c']
values = [1, 2, 3]
dictionary = dict(zip(keys, values))
print dictionary

3. Python奇淫技巧

3.1 求两个list的交集,并集,差集

print list(set(a).intersection(set(b)))   #获取两个 list 的交集
print list(set(a).union(set(b)))        #获取两个 list 的并集
print list(set(b).difference(set(a)))    #获取两个 list 的差集

3.2 优先权队列的用法

from queue import Queue
from queue import PriorityQueue
prioqueue=PriorityQueue()
prioqueue.put((1,'hahaha'))  
prioqueue.put((5,'ustc'))
prioqueue.put((2,'nwsuaf'))
prioqueue.put((3,'tsinghua'))
prioqueue.put((6,'peking'))
prioqueue.put((4,'zhejiang'))
while prioqueue:    
    print (prioqueue.get_nowait())

3.3 import 包

modules所在的目录在Python中叫做package,比如有一个名字叫做MyPackage的package,实际上是一个目录。它的下面有3个文件,分别是: first.py 、second.py 、__init__.py 。 有两种方法调用某目录下的modules。 __init__.py为空时:

from MyPackage import firstfirst.hello()

___init__.py用all=[…]指定该package下可以被imported进去的module

% cat MyPackage/__init__.py__all__=["first","second"]

3.4 排序

在Python中,当需要对一个list排序时,一般可以用 list.sort() 或者 sorted(iterable[, cmp[, key[, reverse]]]).其中:cmp(e1,e2) 是带两个参数的比较函数,返回值:负数(e1 < e2)、0(e1=e2)、正数(e1>e2)。默认为None,即用内建的比较函数。key 是带一个参数的函数,用来为每个元素提取比较值,默认为None,即直接比较每个元素。reverse 是一个布尔值,表示是否反转比较结果。* cmp 使用自定义排序规则来进行排序。比如list中每个元素都是2-tuple,(keyword, weight),我们使用weight来进行排序(从高到低)。可以这样:

def my_cmp(e1, e2):    
    return -cmp(e1[1],e2[1])
a_list=[('aa',1),('bb',2),('cc',3)]
a_list.sort(my_cmp)

如果使用lambda函数:


a_list=[('aa',1),('bb',2),('cc',3)]
a_list.sort(lambda e1,e2: cmp(e1[1],e2[1]))
  • key
    def my_key(e):    
       return e[1]  #return key 11,10,12
    L = [('aa', 11), ('bb', 10), ('cc', 12)]
    L.sort(key=my_key,reverse=1) #key 大到小 reverse=0 时候从小到大
    

如果使用lambda函数:

a_list=[('aa',1),('bb',2),('cc',3)]
a_list.sort(key=lambda e:e[1])

字典排序

dic = {'a':31, 'bc':5, 'c':3, 'asd':4, '33':56, 'd':0}
print sorted(dic.iteritems(), key=lambda d:d[1], reverse = False ) 
#排序后是一个list:  [('d', 0), ('c', 3), ('asd', 4), ('bc', 5), ('a', 31), ('33', 56)]

3.5 列表推导

列表推导(List comprehension)的作用是为了更方便地生成列表(list)。比如,一个list变量的元素均为数字,如果需要将每个元素的值乘以2并生成另外一个list。如果使用列表推导,可以这样:

list1 = [1,2,4,5,12]
list2 = [item*2 for item in list1 ]
print list2

可以通过if过滤掉不想要的元素,例如提取出list1中小于10的元素:

list1 = [1,2,4,5,12]
list2 = [item for item in list1 if item < 10 ]
print list2

如果要将两个list中的元素进行组合,可以:

list1 = [1,2,3]
list2 = [4,5,6]
list3 = [(item1,item2) for item1 in list1 for item2 in list2 ]
print list3

3.6 is和==的区别

Python中的对象包含三要素: id ,、 type、 value其中, id 用来唯一标识一个对象, type 标识对象的类型, value 是对象的值。is判断的是 a对象是否就是b对象, 是通过 id 来判断的==判断的是a对象的值是否和b对象的值相等,是通过 value 来判断的

>>> a=100
>>> b=100.0
>>> a is b
False
>>> a==b
True

3.7 进度条

step=0      
for i in range(0,666):
    step+=1
    if step%10==0:  #显示进度条
        running_fraction=step*100.0/666
        sys.stdout.write(str(running_fraction)+'% \r')
        sys.stdout.flush()  

4、高级话题

4.1 Python特殊语法: lambda 、 filter 、 map 、 reduce

Python内置了一些非常有趣但非常有用的函数,冲分体现了Python语言的魅力!!* lambdalambda函数也叫匿名函数,比如:

def f(x):    
    return x**2    
print f(4)

使用lambda函数,写成这样:

g = lambda x : x**2print g(4)

lambda会创建一个函数对象,但不会把这个函数对象赋值给一个标识符,而def则会把函数对象赋值给一个变量。此外,lambda只是一个表达式,而def则是一个语句。lambda语句被用来创建新的函数对象,并且在运行时返回他们。

print   reduce(lambda  x,y: x*y  , range(1,1001))

reduce(functionA,iterableB),functionA为需要两个变量的函数,并返回一个值。iterableB为可迭代变量,如List等。reduce函数将B中的元素从左到右依次传入函数A中,再用函数A返回的结果替代传入的参数,反复执行,则可将B reduce成一个单值。在此,是将1到1000的连续整数列表传入lambda函数并用两个数的积替换列表中的数,实际的计算过程为:(…((1×2)×3)×4)×…×1000),最后的结果即1000的阶乘。* 关于lambda函数,一些用过的技巧:

list_a_b_c_sorted=sorted(list_a_b_c,key=lambda a_tuple:a_tuple[1]) 
#list_a_b_c是一个列表,列表的元素是一个三元组(a,b,c),按照关键字为b来排序
cluster_list=defaultdict(lambda:[])   #定义了一个字典。value是一个list
  • 为什么使用lambda
  1. 使用Python写一些执行脚本时,使用lambda可以省去定义函数的过程,让代码更加精简。
  2. 对于一些抽象的,不会别的地方再复用的函数,有时候给函数起个名字也是个难题,使用lambda不需要考虑命名的问题。
  3. 使用lambda在某些时候让代码更容易理解。
  • filter

filter(function,sequence) :对 sequence 中的 item 依次执行 function(item) a将执行结果为 True 的 item 组成一个 List/String/Tuple (取决于 sequence 的类型)返回。比如:

def f(x):     
    return x % 2 != 0 and x % 3 != 0 
filter(f, range(2, 25))

打印出: [5, 7, 11, 13, 17, 19, 23]

  • map map(function, sequence) :对 sequence 中的item依次执行 function(item) ,将执行结果组成一个List返回。比如:
    def cube(x):     
       return x*x*x map(cube, range(1, 11))
    

    打印出:[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]

  • reduce reduce(function, sequence, starting_value) :对 sequence 中的 item 顺序迭代调用 function ,如果有 starting_value ,还可以作为初始值调用,例如可以用来对 List 求和:
    def add(x,y):    
      return x + yreduce(add, range(1, 11))
    

    打印出:55 (注:1+2+3+4+5+6+7+8+9+10)

    reduce(add, range(1, 11), 20)
    

    打印出: 75 (注:1+2+3+4+5+6+7+8+9+10+20)

4.2 闭包

  • 什么是闭包?

闭包( closure )是函数式编程的重要的语法结构。函数式编程是一种编程范式(面向过程和面向对象也都是编程范式)。在面向过程中,有函数( function );在面向对象中,有对象( object )。函数和对象的根本目的是以某种逻辑方式组织代码,并且提高代码的可重复使用性( reusability )。闭包也是一种组织代码的结构,它同样提高了代码阿德可重复使用性。

  • 为什么要闭包?

闭包可以有效地减少了函数所需要定义的参数数目。这对于并行运算来说有重要的意义。在并行运算的环境下,让每台电脑负责一个函数,然后将一台电脑的输出和下一台电脑的输入串联起来。最终,像流水线一样工作。从串联的电脑集群一端输入数据,从另一端输出数据。这样的情境最适合只有一个参数输入的函数。闭包就可以实现这一目的。

  • 怎么用闭包?

例题1

def make_add(a):    
    def add(b):        
        return a+b    
    return addp=make_add(23)
q=make_add(44)
print p(100)
print q(100)

打印出:123 144make_add是一个函数,带有一个参数a,这个函数里面又定义了一个新函数,在新函数中,外部传递过来的参数a和自己的参数b绑定在一起了。我们将b看做新函数的一个配置信息,配置信息不同,函数的功能就不一样了,也就是能够得到定制之后的函数。在看一下运行结果,虽然p和q都是make_add生成的,但是因为配置参数不同,后面执行相同的参数后得到了不同的结果,这就是闭包。

例题2

def hellocounter(name):    
    count=0    
    def counter():       
        nonlocal count        
        count+=1        
    print ('Hello,',name,',',str(count)+' access!')    
    return counter
hello = hellocounter('yan')
hello()
hello()
hello()

执行结果(python3.4)

Hello, yan , 1 access!Hello, yan , 2 access!Hello, yan , 3 access!

可以将这个程序看做统计一个函数调用次数的函数。

例题3装饰器

def makebold(fn):    
    def wrapped():        
        return '<b>'+fn()+'</b>'    
    return wrapped
def makeitalic(fn):    
    def wrapped():        
        return '<i>'+fn()+'</i>'    
    return wrapped@makebold@makeitalic
def hello():    
    return 'Hello World'print (hello())

执行结果

<b><i>Hello World</i></b>

这个程序就是传说中的装饰器。装饰器就是一种闭包。装饰器的概念:对函数(参数、返回值等)进行加工处理,生成一个功能增强版的一个函数。

4.3 赋值、浅拷贝、深拷贝

  • 赋值的3种形式:=、对象作为参数、返回值。在Python中,对象的赋值就是简单的对象引用,比如:
list_a=[1,2,3,4,5,6,7]
list_b=list_a

那么 list_b 和 list_a 是一样的,他们指向同一片内存, list_b 是 list_a 的别名,是引用。赋值操作(包括对象作为参数、返回值),不会开辟新的内存空间,它只是复制了新对象的引用。也就是说除了 list_b 这个名字外,没有其他的内存开销。

  • 浅拷贝有3种形式:切片操作,工厂函数,copy模块中的copy函数。比如:
list_b = list_a[:]list_b = [each for each in list_a]  #切片操作
list_b = list(list_a)       # 工厂函数
list_b=copy.copy(list_a)    # copy函数

浅拷贝产生的 list_b 不再是 list_a 了,使用 is 可以发现他们不是同一个对象,用 id 查看他们也不指向同一片内存。但是如果列表元素中有高级结构比如list,那么修改了list_b中的list元素,也会修改list_a中的,因为浅拷贝仅仅拷贝了一层。

  • 深拷贝只有一种形式。 copy 模块中的 deepcopy 函数







Search

    Post Directory