[TOC]
高级特性
切片
取一个list或者tuple中的元素
1
2
3
4
5
6
7
8
9
10 >>> L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']
>>> L[0:3] #从索引0开始取,直到索引3为止,但不包括索引3。
['Michael', 'Sarah', 'Tracy']
>>> L[:3]
['Michael', 'Sarah', 'Tracy']
>>> L[-2:]
['Bob', 'Jack']
>>> L[-2:-1]
['Bob']
1 | >>> L = range(100) |
1 | >>> (0, 1, 2, 3, 4, 5)[:3] |
1 | >>> 'ABCDEFG'[:3] |
迭代
任何可迭代对象都可以作用于for循环,包括我们自定义的数据类型,只要符合迭代条件,就可以使用for循环。
1 | >>> for i, value in enumerate(['A', 'B', 'C']): |
1 | >>> for ch in 'ABC': |
1 | >>> d = {'a': 1, 'b': 2, 'c': 3} |
1 | >>> d = {'x': 'A', 'y': 'B', 'z': 'C' } |
列表生成式
可以快速生成list,代替循环
生成[1x1, 2x2, 3x3, …, 10x10]怎么做?
方法一是循环1
2
3
4
5
6>>> L = []
>>> for x in range(1, 11):
... L.append(x * x)
...
>>> L
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
列表生成试如下:1
[x*x for x in range(1,11)]
写列表生成式时,把要生成的元素x * x放到前面,后面跟for循环,就可以把list创建出来
1 | >>> [x*x for x in range(1,11) if x%2==0] |
1 | >>> L = ['Hello', 'World', 18, 'Apple', None] |
生成器generator
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器(Generator)。
创建方式有两种
1.直接把一个列表生成式的[]改成(),就可以了1
2
3
4
5>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
怎么打印generator呢?可以通过generator的next()方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 >>> g.next()
0
>>> g.next()
1
>>> g.next()
4
>>> g.next()
9
>>> g.next()
16
>>> g.next()
25
>>> g.next()
36
>>> g.next()
49
>>> g.next()
64
>>> g.next()
81
>>> g.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
上面这种方法有点难以接受,于是,我们通常用for循环来打印
1
2
3
4 >>> g = (x * x for x in range(10))
>>> for n in g:
... print n
...
2.采用定义函数的方式来定义generator,只不过函数体内要有yield
.
如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator
求斐波拉契数列
1
2
3
4
5
6 def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
1 | f = fib(6) |
1 | for i in fib(6): |
变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。遇到return语句或者执行到函数体最后一行语句,就是结束generator的指令。