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