在Python中,代码不是越多越好,而是越少越好。代码不是越复杂越好,而是越简单越好。请始终牢记,代码越少,开发效率越高。
切片
>>> L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']
-
切片,取前3个元素
>>> L[0:3]
说明:L[0:3]表示,从索引0开始取,直到索引3为止,但不包括索引3。即索引0,1,2,正好是3个元素。 -
如果第一个索引是0,可以省略
>>> L[:3]
-
倒数切片
>>> L[-2:]
说明:从倒数第二个取,一直取到最后一个 -
前10个数,每两个取一个
>>> L = list(range(100)) //创建一个0-99的list
>>> L[:10:2]
-
复制list
>>> L[:]
-
tuple也可以用切片操作,只是操作的结果仍是tuple
>>> (0, 1, 2, 3, 4, 5)[:3]
-
字符串也可以用切片操作,只是操作结果仍是字符串
>>> 'ABCDEFG'[:3]
列表生成式
- 生成列表:[1x1, 2x2, 3x3, ..., 10x10]
>>> [x * x for x in range(1, 11)]
说明:把要生成的元素x*x放到前面,后面跟for循环,就可以把list创建出来 - if ... else
跟在for后面的if是一个筛选条件,不能带else>>> [x for x in range(1, 11) if x % 2 == 0]
for前面的部分是一个表达式,必须加上else。表达式:x if x % 2 == 0,它无法根据x计算出结果,因为缺少else>>> [x if x % 2 == 0 else -x for x in range(1, 11)]
生成器
定义:列表元素可以按照某种算法推算出来,可以在循环的过程中不断推算出后续的元素。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
- 创建生成器的方法
>>> g = (x * x for x in range(10))
- 通过next()函数获得生成器的下一个返回值:
>>> next(g)
说明:生成器保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。 - 使用for循环也可获取
>>> g = (x * x for x in range(10))
>>> for n in g:
... print(n)
迭代器
- 可迭代对象:可以直接作用于for循环的对象统称为可迭代对象
一类是集合数据类型,如list、tuple、dict、set、str等;
一类是generator,包括生成器和带yield的generator function。 - isinstance()判断一个对象是否是可迭代对象
>>> from collections.abc import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False
- 迭代器:可以被next()函数调用并不断返回下一个值的对象称为迭代器
- 使用isinstance()判断一个对象是否是迭代器对象
>>> from collections.abc import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False
说明:生成器都是可迭代对象,但list、dict、str虽然是可迭代对象,却不是迭代器。
可以这样简单理解,迭代器可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
- 使用iter()函数,把可迭代对象变成迭代器
>>> isinstance(iter([]), Iterator)
生成器和迭代器的总结
-
凡是可作用于for循环的对象都是可迭代类型;
-
凡是可作用于next()函数的对象都是迭代器类型,它们表示一个惰性计算的序列;
-
集合数据类型如list、dict、str等是可迭代对象但不是迭代器,不过可以通过iter()函数变为迭代器。
-
生成器是一种特殊的迭代器(注意这个逻辑关系反之不成立)。
-
合理使用生成器,可以降低内存占用、优化程序结构、提高程序速度。
-
生成器在 Python 2 的版本上,是协程的一种重要实现方式;而 Python 3.5 引入 async await 语法糖后,生成器实现协程的方式就已经落后了。
-
迭代器是一个有限集合,生成器则可以成为一个无限集。调用 next(),生成器根据运算会自动生成新的元素
-
声明一个迭代器,
[i for i in range(10)]
-
声明一个生成器,
(i for i in range(10))
-
生成器并不会像迭代器一样占用大量内存,只有在被使用的时候才会调用。而且生成器在初始化的时候,并不需要运行一次生成操作,相比于迭代器节省了一次生成10个元素的过程,因此耗时明显比迭代器短。