Python的高级特性(切片,迭代,生成器,迭代器)

掌握了python的数据类型,语句和函数,基本上就可以编出很多有用的程序了。
但是在python中,并不是代码越多越好,代码不是越复杂越好,而是越简单越好。
基于这个思想,就引申出python的一些高级特性。

切片

在python中,取list或者是tuple的部分元素是非常常见的操作。

L = ["gege","gege","egye"];
[L[0],L[1],L[2]]

上面这个是一个笨办法,因为扩展一下,取前面n个元素就没办法了。

r = []
n = 3
for i in range(n):
    r.append(i)

还有这种经常取指定索引范围的操作,用循环十分繁琐,所以python提供了切片(Slice)操作符,极大的简化这种操作。类似于javascript中的数组的slice方法。

JavaScript数组中的slice方法

它能够基于当前数组中的一个或多个项创建一个新数组。slice()方法可以接受一个或两个参数,即要返回项的起始位置和结束位置。
在只有一个参数的情况下,slice方法返回从该参数指定位置开始到当前数组末尾的所有项。
如果有两个参数,该方法返回起始和结束位置之间的项,但是不包括结束位置的项。
注意:slice方法不会影响原始数组。
对于上面的问题,想要取前面三个元素。直接就用

L[0:3]
//也可以省略0:
L[:3]

类似的,python数组支持负数索引,切片也支持倒数切片,记住倒数第一个元素的索引是-1.
还可以取不连续的数

L = list(range(100));
L[:10] //   前10个数
L[-10:] //后10个数
L[:10:2] //前10个数,每两个取一个
L[:] //原样复制一个list

tuple也是一种list,唯一的区别是tuple不可变,因此tuple也可以使用切片操作,只是操作的结果仍然是tuple。

(0,1,2,3,4)[:3]
//(0,1,2)

字符串‘xxxx’也可以看成是一种list,每个元素就是一个字符,因此字符串也可以做切片,只是操作的结果还是字符串

“ffeefg”[:3]

其实其他编程语言对字符串也有很多操作,如substring,目的就是对字符串进行切片,python没有针对字符串的截取函数,只需要一个切片操作就可以完成,非常简单。

迭代

在python中,迭代是通过for... in循环来操作的,不仅可以作用在list或tuple上,还可以作用在其他可迭代对象上。

//dict
d = {'a':1,'b':2,'c':3}
for key in d:
    print(key)

for value in d.values():
    print(value)

for k,v in d.items():
    print(k,v)

//字符串
for ch in 'abc':
    print(ch)

使用for循环时,不管是什么数据类型,只要是一个可迭代对象就行,那如何判断是一个可迭代对象呢?
使用collections模块的Iterable类型判断

from collections import Iterable
isinstance('abc',Iterable) //true
# str是否可迭代
isinstance([1,2,3],Iterable) //true
# list是否可迭代
isinstance(123,Iterable) //false
# 整数是否可迭代

Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以for循环中同时迭代索引和元素本身了。

for i,value in enumerate(['s','ss','sss']):
    print(i,value)

列表生成式

[x*x for x in range(1,11)]
//把要生成的元素放在前面
[x*x for x in range(1,11) if x%2 == 0]
//for循环后面还可以加上if判断

[m+n for m in 'ABC' for n in 'XYZ']
//['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
//可以使用两层循环,生成全排列
三层以及三层以上就很少用

生成器(generator)

通过列表生成式在列表容量很大的时候就会占用很多空间
所以生成器就派上用场了,一遍循环一遍计算的机制
定义generator的第一种方法,

 g = (x * x for x in range(10))
for n in g:
    print(n)

创建了一个generator后,基本上永远不会调用next(),而是通过for循环来迭代它,并且不需要关心StopIteration的错误

著名的斐波拉契数列

定义generator的第二种方法


def fib(max):
    n,a,b = 0,0,1
    while n < max:
       // print(b) 
        yield b
        a,b = b,a+b
        n = n + 1

将上面的print(b)改成yield b,就是一个generator。

原文地址:https://www.cnblogs.com/sminocence/p/7898643.html