1 切片
取前N个元素,也就是索引为0-(N-1)的元素:
L[0:N]
第一个索引为0时,可以省略:
还可以倒序切片:
记住倒数第一个元素的索引是-1
切片其他操作:
先创建一个0-99的数列:
前10个数,以步长为2取数(与matlab不同,步长在第三个位置):
甚至什么都不写,只写[:]就可以原样复制一个list:
tuple也是一种list,唯一区别是tuple不可变。因此,tuple也可以用切片操作,只是操作的结果仍然是tuple
字符串也可以看成是一种list,每个元素就是一个字符。因此,字符串也可以用切片操作,只是操作结果仍是字符串:
在很多编程语言中,针对字符串提供了很多各种截取函数,其目的就是对字符串进行切片。而Python没有类似函数,只需要切片一个操作就可以完成。
2 迭代
给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration)
在Python中,迭代是通过for … in …来完成。
这不仅可以用在list或tuple上,还可以作用在其他可迭代对象上。只要是可迭代对象,无论有无下标,都可以迭代,比如dict:
默认情况下,dict迭代的是key。如果要迭代value,可以用for value in d.values()
。如果要同时迭代key和value,可以用for k, v in d.items
。
由于字符串也是可迭代对象,因此,也可以作用于for循环:
所以,当我们使用for循环时,只要作用于一个可迭代对象,for循环就可以正常运行。
那么,如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断:
最后,如果要对list实现下标循环怎么办?Python内置的enumerate
函数可以把一个list变成索引-元素对,这样就可以zaifor循环中同时迭代索引和元素本身:
上面的for循环里,同时引用了两个变量,在Python里是很常见的,比如下面的代码:
3 列表生成式
列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。
举个例子,要生成list[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]可以:
但是要生成[1x1, 2x2, 3x3, …,10x10]怎么做呢?方法一是循环:
但是循环太繁琐,而列表生成式则可以用一行语句代替循环生成上面的list:
for循环后还可以加上if判断:筛选偶数的平方
还可以使用两层循环,生成全排列:
运用列表生成式,可以写出非常简洁的代码。例如,列出当前目录下的所有文件和目录名:
列表生成式也可以使用两个变量来生成list:
例子:后把一个list中所有的字符串变成小写:
如果list中既包括字符串,又包含整数:
解决方法:
>>> L=['Hello', 'World', 18]
>>> [s.lower() for s in L if isinstance(s, str)]
['hello', 'world']
4 生成器
通过列表生成式,我们可以直接创建一个列表。但是,收到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
在Python中,有一种一边循环一边推算列表元素的机制,称为生成器:generator。
要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成()。就创建一个generator:
如果要把生成器的元素一个个打印出来,可以使用next()函数获得生成器的下一个返回值:
生成器保存的是元素推断算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多元素时,抛出StopIteration的错误。
生成器也是可迭代对象:
所以,我们创建一个生成器后,基本不会调用next(),而是通过for循环来迭代它。
函数与生成器:
如果一个函数定义中包含yield关键字,那么这个函数就变成了生成器了。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成生成器的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
例子:
调用该生成器时,首先要生成一个生成器对象,然后用next()函数不断获得下一个返回值:
5 迭代器
我们知道,可以直接作用于for循环的数据类型有以下几种:
一类是集合数据类型:如list tuple dict set str 等;
一类是generator, 包括生成器和带yield的generator function。
这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。
可以使用isinstance()判断一个对象是否是Iterable对象:
而生成器不但可以作用于for循环,还可以被next()函数不断调用返回下一个值,直到最后抛出StopIteration错误。
可以被next()函数调用并不断返回下一个值得对象称为迭代器:Iterator。
可以使用isinstance()判断一个对象是否是Iterator对象:
生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。
把它们变成Iterator可以使用iter()函数:
为什么list、dict、str等数据类型不是Iterator?
这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看作是一个由序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。