python---高级特性
##################################
############### 迭代 ##############
##################################
1.迭代定义
可以通过 for 循环来遍历这个 list 或 tuple,这种遍历我们称为迭代(Iteration)
2.判断可迭代对象
方法是通过 collections 模块的 Iterable 类型判断
In [1]: from collections import Iterable
In [2]: isinstance('abc',Iterable)
Out[2]: True
In [3]: isinstance('{"name":"fentiao"}',Iterable)
Out[3]: True
In [4]: isinstance([1,2,3],Iterable)
Out[4]: True
In [5]: isinstance(1,Iterable)
Out[5]: False

In [1]: d = {'name':'fentiao','age':5,'gender':'male'}
In [2]: for k in d:
...: print k
...:
gender
age
name
In [3]: for k,v in d:
...: print k,v
...:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-3-57f4828128ce> in <module>()
----> 1 for k,v in d:
2 print k,v
3
ValueError: too many values to unpack

2)如果要迭代 value:
In [4]: for k,v in d.iteritems():
...: print k,v
...:
gender male
age 5
name fentiao

In [5]: for i,value in enumerate([1,2,3,4]):
...: print i,value
...:
0 1
1 2
2 3
3 4

...: print x,y
...:
1 2
2 3
3 4

##############################
1.列表生成式定义
列表生成式是Python 内置的非常简单却强大的可以用来创建 list的生成式
思考:
要生成 list [1, 2, 3, 4, 5, 6, 7] 可以用 range(1, 8)
但如果要生成 [1x1, 2x2, 3x3, ..., 7x7] 怎么做?
方法一:for循环
In [7]: li = []
In [8]: for x in range(1,8):
...: li.append(x*x)
...:
In [9]: li
Out[9]: [1, 4, 9, 16, 25, 36, 49]

方法二:列表生成式
In [10]: [x*x for x in range(1,8)]
Out[10]: [1, 4, 9, 16, 25, 36, 49]

循环太繁琐,而列表生成式则可以用一行语句代替循环生成上面的 list.
2.列表生成式嵌套语句
1)生成20以内所有偶数的平方:
In [11]: [ i*i for i in range(0,20) if i %2 == 0 ]
Out[11]: [0, 4, 16, 36, 64, 100, 144, 196, 256, 324]
Out[13]: ['1A', '1B', '1C', '2A', '2B', '2C', '3A', '3B', '3C']

d = {'name':'hello','age':'5'}
print [ k+'='+v for k,v in d.items()]
结果:['age=5', 'name=hello']
print [i.lower() for i in li if isinstance(i, str)]
结果:['hello', 'world']

##############################
1.为什么需要生成器
• 通过列表生成式,我们可以直接创建一个列表,受到内存限制,列表容量肯定是有限的;
• 列表生成式如果只需要前几个元素,浪费内存空间;
2.生成器含义
在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的 list,从而节省大量的空间。在 Python 中,这种一边循环一边计算的机制,称为生成器(Generator)
3.创建生成器
把一个列表生成式的 [] 改成 ()
4.访问生成器
1)使用g.next()方法依次读取元素(麻烦)
2)使用 for 循环(推荐)
In [2]: l = [i for i in range(10)] # 列表生成式
In [3]: l
Out[3]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [4]: g = (i for i in range(10)) # 生成器
In [5]: g.next() # g.next()方法依次读取
Out[5]: 0
In [6]: g.next()
Out[6]: 1
In [7]: g.next()
Out[7]: 2
In [8]: for i in g: # for 循环
...: print i
...:
3
4
5
6
7
8
9

# fib 函数定义了斐波拉契数列的推算规则,可以从第一个元素开始,推算出后续任意的元素,逻辑非常类似generator。
def fib(max):
n,a,b = 0,0,1
while n < max:
print b
a,b = b,a+b
n += 1
fib(6)
n,a,b = 0,0,1
while n < max:
yield b
a,b = b,a+b
n += 1
for x in fib(6):
print x
yield 语句处继续执行
def hello():
print 'a'
yield 1
print 'b'
yield 2
print 'c'
yield 3
a = hello()
a.next() # 第一次调用next(),进入generator函数,函数顺序执行,遇到yield 1 语句返回'a'
a.next() # 第二次调用next(),进入generator函数,函数顺序执行,遇到yield 2 语句返回'b'
a.next() # 第三次调用next(),进入generator函数,函数顺序执行,遇到yield 3 语句返回'c'

import time
def consumer(name):
print '%s 准备吃午饭了!'%(name)
while True:
fentiao = yield 3# 遇到yield返回到c1.next()继续执行producer('Mary')
5# 遇到yield返回到c2.next()继续执行producer('Mary')
print ('午饭[%s]做出来了,被[%s]吃了')%(fentiao,name)
def producer(name):
c1 = consumer('Tom')
c2 = consumer('Jack')
c1.next() 2# 调用c1.next(),执行consumer('Tom')
c2.next() 4# 调用c2.next(),执行consumer('Jack')
print '开始做午饭了。。。。'
for i in range(1,3):
time.sleep(1)
print '[%s]做了两份午饭,两个人一起吃'%(name)
c1.send(i) 6# c1.send(),返回到c1的yield 语句处继续执行consumer('Tom')
c2.send(i) 7# c2.send(),返回到c2的yield 语句处继续执行consumer('Jack')
producer('Mary') 1# 执行producer('Mary')
结果:Tom 准备吃午饭了!
Jack 准备吃午饭了!
开始做午饭了。。。。
[Mary]做了两份午饭,两个人一起吃
午饭[1]做出来了,被[Tom]吃了
午饭[1]做出来了,被[Jack]吃了
[Mary]做了两份午饭,两个人一起吃
午饭[2]做出来了,被[Tom]吃了
############### 迭代 ##############
##################################
1.迭代定义
可以通过 for 循环来遍历这个 list 或 tuple,这种遍历我们称为迭代(Iteration)
2.判断可迭代对象
方法是通过 collections 模块的 Iterable 类型判断
In [1]: from collections import Iterable
In [2]: isinstance('abc',Iterable)
Out[2]: True
In [3]: isinstance('{"name":"fentiao"}',Iterable)
Out[3]: True
In [4]: isinstance([1,2,3],Iterable)
Out[4]: True
In [5]: isinstance(1,Iterable)
Out[5]: False
3.字典的迭代
1)默认情况下,dict 迭代的是 key:In [1]: d = {'name':'fentiao','age':5,'gender':'male'}
In [2]: for k in d:
...: print k
...:
gender
age
name
In [3]: for k,v in d:
...: print k,v
...:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-3-57f4828128ce> in <module>()
----> 1 for k,v in d:
2 print k,v
3
ValueError: too many values to unpack
2)如果要迭代 value:
In [4]: for k,v in d.iteritems():
...: print k,v
...:
gender male
age 5
name fentiao
4.list实现下标循环
python内置的枚举方法enumerate,把一个 list 变成索引元素对In [5]: for i,value in enumerate([1,2,3,4]):
...: print i,value
...:
0 1
1 2
2 3
3 4
5.for 循环里,同时引用了两个变量,实现迭代显示
In [6]: for x,y in [(1,2),(2,3),(3,4)]:...: print x,y
...:
1 2
2 3
3 4
##############################
########## 列表生成式 #######################################
1.列表生成式定义
列表生成式是Python 内置的非常简单却强大的可以用来创建 list的生成式
思考:
要生成 list [1, 2, 3, 4, 5, 6, 7] 可以用 range(1, 8)
但如果要生成 [1x1, 2x2, 3x3, ..., 7x7] 怎么做?
方法一:for循环
In [7]: li = []
In [8]: for x in range(1,8):
...: li.append(x*x)
...:
In [9]: li
Out[9]: [1, 4, 9, 16, 25, 36, 49]
方法二:列表生成式
In [10]: [x*x for x in range(1,8)]
Out[10]: [1, 4, 9, 16, 25, 36, 49]
循环太繁琐,而列表生成式则可以用一行语句代替循环生成上面的 list.
2.列表生成式嵌套语句
1)生成20以内所有偶数的平方:
In [11]: [ i*i for i in range(0,20) if i %2 == 0 ]
Out[11]: [0, 4, 16, 36, 64, 100, 144, 196, 256, 324]
2)生成‘ABC’与‘123’的全排列:
In [13]: [i+n for i in '123' for n in 'ABC']Out[13]: ['1A', '1B', '1C', '2A', '2B', '2C', '3A', '3B', '3C']
3.列表生成式使用两个变量来生成list
1)生成字典的的内容,格式为‘key=value’,返回其列表格式d = {'name':'hello','age':'5'}
print [ k+'='+v for k,v in d.items()]
结果:['age=5', 'name=hello']
2)将list中所有的字符串变为小写字母
li = ['HEllo', 'World', 1]print [i.lower() for i in li if isinstance(i, str)]
结果:['hello', 'world']
##############################
############ 生成器 #########################################
1.为什么需要生成器
• 通过列表生成式,我们可以直接创建一个列表,受到内存限制,列表容量肯定是有限的;
• 列表生成式如果只需要前几个元素,浪费内存空间;
2.生成器含义
在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的 list,从而节省大量的空间。在 Python 中,这种一边循环一边计算的机制,称为生成器(Generator)
3.创建生成器
把一个列表生成式的 [] 改成 ()
4.访问生成器
1)使用g.next()方法依次读取元素(麻烦)
2)使用 for 循环(推荐)
In [2]: l = [i for i in range(10)] # 列表生成式
In [3]: l
Out[3]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [4]: g = (i for i in range(10)) # 生成器
In [5]: g.next() # g.next()方法依次读取
Out[5]: 0
In [6]: g.next()
Out[6]: 1
In [7]: g.next()
Out[7]: 2
In [8]: for i in g: # for 循环
...: print i
...:
3
4
5
6
7
8
9
5.手动实现生成器
1)定义一函数fib,实现斐波那契数列(Fibonicci):1, 1, 2, 3, 5, 8, 13, 21....# fib 函数定义了斐波拉契数列的推算规则,可以从第一个元素开始,推算出后续任意的元素,逻辑非常类似generator。
def fib(max):
n,a,b = 0,0,1
while n < max:
print b
a,b = b,a+b
n += 1
fib(6)
# 要把 fib 函数变成 generator,只需要把print b 改为 yield b 就可以.
def fib(max):n,a,b = 0,0,1
while n < max:
yield b
a,b = b,a+b
n += 1
for x in fib(6):
print x
2)如何理解关键字yield和next()
generator函数在每次调用next() 的时候执行,遇到 yield 语句返回,再次执行时从上次返回的yield 语句处继续执行
def hello():
print 'a'
yield 1
print 'b'
yield 2
print 'c'
yield 3
a = hello()
a.next() # 第一次调用next(),进入generator函数,函数顺序执行,遇到yield 1 语句返回'a'
a.next() # 第二次调用next(),进入generator函数,函数顺序执行,遇到yield 2 语句返回'b'
a.next() # 第三次调用next(),进入generator函数,函数顺序执行,遇到yield 3 语句返回'c'
6. 通过yield实现单线程的并发运算
异步I/O模型epoll http nginx tomcatimport time
def consumer(name):
print '%s 准备吃午饭了!'%(name)
while True:
fentiao = yield 3# 遇到yield返回到c1.next()继续执行producer('Mary')
5# 遇到yield返回到c2.next()继续执行producer('Mary')
print ('午饭[%s]做出来了,被[%s]吃了')%(fentiao,name)
def producer(name):
c1 = consumer('Tom')
c2 = consumer('Jack')
c1.next() 2# 调用c1.next(),执行consumer('Tom')
c2.next() 4# 调用c2.next(),执行consumer('Jack')
print '开始做午饭了。。。。'
for i in range(1,3):
time.sleep(1)
print '[%s]做了两份午饭,两个人一起吃'%(name)
c1.send(i) 6# c1.send(),返回到c1的yield 语句处继续执行consumer('Tom')
c2.send(i) 7# c2.send(),返回到c2的yield 语句处继续执行consumer('Jack')
producer('Mary') 1# 执行producer('Mary')
结果:Tom 准备吃午饭了!
Jack 准备吃午饭了!
开始做午饭了。。。。
[Mary]做了两份午饭,两个人一起吃
午饭[1]做出来了,被[Tom]吃了
午饭[1]做出来了,被[Jack]吃了
[Mary]做了两份午饭,两个人一起吃
午饭[2]做出来了,被[Tom]吃了
午饭[2]做出来了,被[Jack]吃了