5.1切片
1.切片
取一个list或tuple的部分元素是非常常见的操作。例如:
>>>L=['bob','jack']
当要取list的前N个元素时,通常通过循环遍历该list,然后取出索引在0~(N-1)范围内的元素
>>>r=[]
>>>n=2
>>>for i in range(n):
r.append(L[i])
>>>r
['bob','jack']
使用切片的操作可以取一定范围内的元素
L[a,b]
表示从索引是a开始取,直到索引b为止,但不包括b
如果第一个索引是0,可以省略
2.倒数切片
>>>L[-2:]
['bob','jack']
>>>L[-2:-1]
['bob']
倒数第一个元素的索引是-1
3.切片的简单应用
L=list(range(100)) #创建一个0~99的列表
通过切片取出一段数列
L[:10] #取出前10个数
后10个数:
L[-10:]
前10个数每2个取一个:
L[:10:2]
所有数,每5个取一个:
L[: : 5]
只写[: ]可以复制一个list
4.Tuple切片
tuple也是一种list,唯一区别是tuple不可变
tuple也可用切片操作,只是操作的结果仍然是tuple
(1,2,3,4,5)[:3]
(1,2,3)
5.字符串切片
字符串’XXX‘也可以看成是一种list,每个元素就是一个字符,因此字符串也可以用切片操作,
只是操作结果仍然是字符串
3.5.2迭代
对于给定的list或tuple可以使用for循环来遍历这个list或者tuple,这种遍历叫做迭代(Iteration)
使用for …in来完成
1.可迭代对象的迭代
列表这种数据类型有下标,其他数据类型没有下标
是要是可迭代对象没有下标依旧可以完成
(1)字典的迭代
d={'a':1,'b':2}
for key in d:
print (key)
由于字典是无序的,因此迭代的结果顺序可能每次不同
默认情况下dict迭代的是key
如果迭代value,可以用for value in d.values()
如果要同时迭代key和value,可以使用for k,v in d.items()
for k, v in d.items():
print(k,v)
(2)集合的迭代
>>>s=set([1,2,3,4])
>>>s
{1,2,3,4}
>>>for x in s:
print(x)
(3)字符串的迭代
for ch in ’ABC‘:
print(ch)
2.Iterable类型判断是否为一个可迭代对象
对于一个对象,通常collections模块的Iterable类型判断是否为一个可迭代对象
例如:
from collections import Iterable
isInstance('abc',Iterable)
True
3.列表实现下标循环
如果需要对list实现类似Java那样的下标,Python内置的enumrate函数可以把一个list变成索引——元素对,这样可以在for循环中同时迭代索引和元素本身
for i,value enumerate(['A','B','C']):
print(i,value)
for循环里面使用同时引用两个变量,在Python里很常见:
for x, y in [(1,1),(2,2),(3,3),(4,4)]:
print(x,y)
5.3列表生成式(用来创建list的生成式)
1.一层循环
要生成list[1,2,3,4,5],可用list(range(1,11))
如果要生成[11,22,33…1010]
L=[]
for x in range(1,11):
L.apeend(x*x)
利用列表生成式可以用一行语句来代替循环生成上面的list
[x*x for x in range(1,11)]
写列表生成式时,把要生成的元素x*x放在前面,后面跟for循环,就可以把list创建出来
for循环后面可以添加if判断
[x*x for x in range(1,11) if x%2==0]
2.使用两层循环,生成全排列
[m+n for m in 'ABC' for n in 'xyz']
['Ax','Ay','Az','Bx','By','Bz','Cx','Cy','Cz']
for循环可以同时使用两个甚至多个变量,比如dict的items()可以同时迭代key和vlue
d={'x':'a','y':'b'}
for k,v in d.items():
print(k,'=',v)
d={'x':'a','y':'b'}
[k+'='+v for k,v in d.items()]
['y=b','x=a']
5.4生成器
简单生成器
在Python中,一遍循环一遍计算的机制,称为生成器
1.简单生成器
创建:第一种方法:只是把一个列表生成式的[]改成(),就创建了一个generator
创建L和g的区别仅在最外层的[]和()
L=[x*x for x in range(10)]
L
g=(x*x for x in range(10))
g
推荐大家使用列表生成式,但读者需要生成大量可迭代对象,最好不要使用列表生成式
生成器可以在当前的圆括号内直接使用,例如可以直接用在函数调用中
>>>sum(x*x for x in range(10))
285
可以通过next()函数获得generator的下一个返回值。generator保存的是算法,每次调用next(g)
计算出g的下一个元素,直到计算到最后一个元素,没有更多元素时,抛出StopIteration
正确的方法是使用for循环
g=(x*x for x in range (10))
for n in g:
print n
带yeid语句的生成器
def fib(max):
n,a,b=0,0,1
while n<max:
print(b)
a,b=b,a+b
n=n+1
return 'done'
t=(b,a+b)
a=t[0]
b=t[1]
上面的函数和generator仅一步之遥。要把fib函数变成generator,只需要把print(b)改成yield b
定义generator的另一种方法。如果一个函数定义中包含yeid关键字,
那么这个函数就不再是一个普通函数,而是一个generator
而generator函数在每次调用next()的时候执行,遇到yield语句返回,再次执行时返回的yield语句继续执行
也就是遇到yield语句需要阻塞
使用for循环调用generator时,发现拿不到generator的return语句的返回值,如果想要拿到返回值,必须捕获stopIteration错误,返回包含在StopIteration的value中
try:
x=next(g)
except StopIteration as e:
print('Generator return生成器
value:',e.value)
break
3.递归生成器
每层嵌套需要增加一个for循环,但不知道有几层嵌套
def flatten(nested):
try:
for sulist in nested:
for element in flatten(sublist):
yield element
exceptTypeError:
yield nested
当flatten 被调用的时候,大致有两种情况,基本情况和需要递归的情况
在基本情况中,函数被告知展开一个元素,这种情况下,for循环会引起一个TypeError异常,生成器会产生一个元素