python day3
本节内容:
切片
迭代
列表生成式
生成器
迭代器
一、切片
切片操作是:针对具有下标的类型的操作。切片帮我可以取出一种数据类型中的部分数据。
例如:
# 列表:切片返回的还是一个列表 a=[1,2,3,4,5,6,7,8,9,10] # 取出前3个元素 print(a[0:3]) print(a[:]) print(a[1:]) # 记住倒数第一个元素的索引是-1。 print(a[-5:]) # 元组:切片返回的还是一个元组 b=(1,2,3,4,5,6,7,8) # 取出前3个元素 print(b[0:3]) print(b[:]) print(b[1:]) # 记住倒数第一个元素的索引是-1。 print(b[-5:]) # 字符串:切片返回的还是一个字符串 c="Drango War" #取出字符串的前3个字符 print(c[0:3]) print(c[:]) print(c[1:]) # 记住倒数第一个元素的索引是-1。 print(c[-5:])
在很多编程语言中,针对字符串提供了很多各种截取函数(例如,substring),其实目的就是对字符串切片。Python没有针对字符串的截取函数,只需要切片一个操作就可以完成,非常简单。
二、迭代
我们通常在代码中会对列表、元组来进行循环遍历出所有的值,这种遍历我们称为"迭代"(Iteration)。
在Python中,迭代是通过for ... in
来完成的 ,python的for循环不是通过下标来执行的,所以在python中很多没有下标的数据类型,也可以通过for...in来完成遍历。只要是可迭代的对象就可以通过for...in来完成。
names=['悟空','八戒','悟静','唐胖'] for name in names: print(name)
在python中:list、tuple 、set、dict、str都是可迭代对象
但是有时我们需要下标怎么办:在python中提供了一个函数:enumerate函数可以把一个list变成索引-元素对
for index,name in enumerate(names): print(index,name) 0 悟空 1 八戒 2 悟静 3 唐胖
三、列表生成式
顾名思义,列表生成式就是一个用来生成列表的特定语法形式的表达式。
[exp for iter_var in iterable]
b=[n for n in range(10)] print(b) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
其实列表生成式也是Python中的一种“语法糖”,也就是说列表生成式应该是Python提供的一种生成列表的简洁形式,应用列表生成式可以快速生成一个新的list。它最主要的应用场景是:根据已存在的可迭代对象推导出一个新的list
四、生成器
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
创建生成器:
要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]
改成()
,就创建了一个generator
b=(n for n in range(10)) print(type(b)) <class 'generator'>
使用包含yield的函数来生成
# 使用包含yield的函数构造生成器 def my_range(start, end): for n in range(start, end): yield 2*n + 1 c=my_range(1,9) print(type(c)) <class 'generator'>
如果计算过程比较简单,可以直接把列表生成式改成generator;但是,如果计算过程比较复杂,就只能通过包含yield的函数来构造generator。
生成器的执行过程:
在执行过程中,遇到yield关键字就会中断执行,下次调用则继续从上次中断的位置继续执行
生成器的特性:
- 只有在调用时才会生成相应的数据
- 只记录当前的位置
- 只能next,不能prev
生成器的调用方式
要调用生成器产生新的元素,有两种方式:
- 调用内置的next()方法
- 使用循环对生成器对象进行遍历(推荐)
- 调用生成器对象的send()方法
遍历生成器:
print(next(c)) print(next(c)) print(next(c))
使用循环遍历:
for i in c: print(i)
使用send方法
print(c.send(None)) print(c.send(None)) 3 5
五、迭代器
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。
可以直接作用于for
循环的数据类型有以下几种:
一类是集合数据类型,如list
、tuple
、dict
、set
、str
等;
一类是generator
,包括生成器和带yield
的generator function。
这些可以直接作用于for
循环的对象统称为可迭代对象:Iterable
。
可以使用isinstance()
判断一个对象是否是Iterable
对象:
from collections import Iterator print(isinstance([], Iterator)) print(isinstance({}, Iterator)) print(isinstance('abc', Iterator)) False False False
生成器都是Iterator
对象,但list
、dict
、str
虽然是Iterable
,却不是Iterator
。
把list
、dict
、str
等Iterable
变成Iterator
可以使用iter()
函数:
from collections import Iterator print(isinstance(iter([]), Iterator)) True
小结
凡是可作用于for
循环的对象都是Iterable
类型;
凡是可作用于next()
函数的对象都是Iterator
类型,它们表示一个惰性计算的序列;
集合数据类型如list
、dict
、str
等是Iterable
但不是Iterator
,不过可以通过iter()
函数获得一个Iterator
对象