Slice、Iteration、List generation、Generator
1 | L = [] |
1. Slice
1 | L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack'] |
tuple也是一种list,唯一区别是tuple不可变。因此,tuple也可以用切片操作,只是操作的结果仍是tuple
1 | (0, 1, 2, 3, 4, 5)[:3] |
字符串'xxx'或Unicode字符串u'xxx'也可以看成是一种list,每个元素就是一个字符。因此,字符串也可以用切片操作,只是操作结果仍是字符串:
1 | 'ABCDEFG'[:3] |
2. Iteration
只要是可迭代对象,无论有无下标,都可以迭代,比如dict就可以迭代
1 | for (i=0; i<list.length; i++) { |
1 | d = {'a': 1, 'b': 2, 'c': 3} |
1 | for ch in 'ABC': |
如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断:
1 | from collections import Iterable |
如果要对list实现类似Java那样的下标循环怎么办?Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身:
1 | for i, value in enumerate(['A', 'B', 'C']): |
for循环里,同时引用了两个变量,在Python里是很常见
1 | for x, y in [(1, 1), (2, 4), (3, 9)]: |
3. List Generation
1 | [x * x for x in range(1, 11) if x % 2 == 0] |
还可以使用两层循环,可以生成全排列:
1 | [m + n for m in 'ABC' for n in 'XYZ'] |
运用列表生成式,可以写出非常简洁的代码。
例如,列出当前目录下的所有文件和目录名
1 | import os # 导入os模块,模块的概念后面讲到 |
for循环其实可以同时使用两个甚至多个变量,比如dict的iteritems()可以同时迭代key和value:
1 | d = {'x': 'A', 'y': 'B', 'z': 'C' } |
列表生成式也可以使用两个变量来生成list:
1 | d = {'x': 'A', 'y': 'B', 'z': 'C' } |
最后把一个list中所有的字符串变成小写:
1 | L = ['Hello', 'World', 'IBM', 'Apple'] |
小结
运用列表生成式,可以快速生成list,可以通过一个list推导出另一个list,而代码却十分简洁。
4. Generator
如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器(Generator)
要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:
1 | L = [x * x for x in range(10)] |
generator 是一个可迭代的对象
1 | g = (x * x for x in range(10)) |
斐波拉契数列
1 | def fib(max): |
fib函数实际上是定义了斐波拉契数列的推算规则,可以从第一个元素开始,推算出后续任意的元素,这种逻辑其实非常类似generator。
把fib函数变成generator,只需要把 print b 改为 yield b 就可以了
1 | def fib(max): |
如果一个函数定义中包含
yield关键字,那么这个函数就不再是一个普通函数,而是一个generator
1 | fib(6) |
函数是顺序执行,遇到
return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
1 | def odd(): |
小结
generator是非常强大的工具,在Python中,可以简单地把列表生成式改成generator,也可以通过函数实现复杂逻辑的generator。
要理解generator的工作原理,它是在for循环的过程中不断计算出下一个元素,并在适当的条件结束for循环。对于函数改成的generator来说,遇到return语句或者执行到函数体最后一行语句,就是结束generator的指令,for循环随之结束。
Checking if Disqus is accessible...