栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

python中非常有用的高级特性(切片、迭代、列表生成式、生成器、迭代器)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python中非常有用的高级特性(切片、迭代、列表生成式、生成器、迭代器)

在python中,代码不是越多越好,而是越少越好,代码越少,开发效率越高

切片:

取一个list和tuple的部分元素是非常常见的

>>>L=['a','b','c','d']

>>>L[0:3]

['a','b','c']

L[0:3]表示,从索引0开始取,直到索引3为止,但不包括索引3,即0,1,2,正好3个元素。

如果第一个索引是0,还可以省略:

>>>L[:3]

['a','b','c']

也可以从索引2取1个元素出来

>>>L[2:3]

['c']

同时支持倒数切片:

倒数第一个元素的索引是-1

>>>L[-2:]

['c','d']

>>>L[-2:-1]

['c']

切片操作十分有用,比如:

我们先创建一个0-99的数列

>>>L = list(range(100))

>>>L

[0,1,2,3,4,…99]

可以通过数列轻松取出某一段数列:

比如:

取前5个数

>>>L[:5]

[0,1,2,3,4]

取后5个数

>>>L[-5:]

[95,96,97,98,99]

前5-10个数:

>>>L[5:10]

[5,6,7,8,9]

前10个数,每两个取一个:

>>>L[:10:2]

[0,2,4,6,8]

所有数,每10个取一个:

>>>L[::10]

[0,10,20,30,40,50,60,70,80,90]

只写[:]可以复制一个list

>>>L[:]

[0,1,2,……99]

tuple也可以用切片操作,只是操作结果还是tuple:

>>>(0,1,2,3,4,5)[:3]

(0,1,2)

字符串也可以用切片操作,只是操作结果还是字符串:

>>>'ABCDEFG'[:3]

'ABC'

小结:有了切片操作,很多地方循环就不再需要了。

迭代:

如果给定一个list或者tuple,我们可以通过for循环来遍历这个list或者tuple,这种遍历我们称为迭代(Iteration)

很多语言比如c语言或者java语言,迭代是通过list下标完成的。

在python中,迭代是通过for…in来完成的,它的for循环抽象程度要高于java的for循环。因为python的for循环不仅可以作用在list或者tuple上,还可以作用在其它可迭代的对象上。

比如:

dict就可以迭代:

>>>d={'a':1,'b':2,'c':3}

>>>for key in d:

…print(key)

输出结果:

a

c

b

因为dict的存储不是按照list的方式顺序排列的,所以,迭代的结果顺序很可能不一样。

默认情况下,dict迭代的是key,如果要迭代value,可以用for value in d.value(),如果要同时迭代key和value,可以用 for k,v in d.items()

字符串也是可迭代对象,因此,也可以作用于for循环:

>>>for ch in 'ABC':

>>>print(ch)

输出结果:

A

B

C

所以,当我们使用for循环时,只要作用于一个可迭代对象,for循环就可以正常运行了,而我们不太关心该对象究竟是list还是其他数据类型。

那么如何判断一个对象是可迭代对象呢?

可以通过collections模块的Iterable类型判断:

>>>from collections import Iterable

>>>isinstance('abc',Iterable)

True

>>>isinstance([1,2,3],Iterable)

True

>>isinstance(123,Iterable)

False

如果要对list实现类似java那样的下标循环怎么办?

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

>>>for i,value in enumerate(['A','B','C']):

>>>print(i,value)

输出结果:

0 A

1 B

2 C

列表生成式:

列表生成式,是python内置的非常简单且强大的可以用来创建list的生成式

比如:

要生成list[1,2,3,4,5]可以用list(range(1,6))

>>>list(range(1,6))

[1,2,3,4,5]

如果要生成[1x1,2x2,3x3,4x4,5x5]怎么做?

方法一:

循环:

>>>L =[]

>>> for x in range(1,6):

>>>L.append(x*x)

>>>L

[1,4,9,16,25]

上面的循环太繁琐,可以用列表生成式代替循环生成上面的list

>>>[x*x for x in  range(1,6)]

[1,4,9,16,25]

写列表生成式时,把要生成的元素x*x放在前面,后面跟for循环,就可以将list创建出来了。

for循环后面还可以加上if判断:

比如:筛选出偶数的平方

>>>[x*x  for in range(1,6) if x%2 ==0]

[4,16]

dict的items()可以同时迭代key和value:

>>>d={'x':'a','y':'b','z':'c'}

>>> for k,v in d.items()

>>>print(k,'=',v)

输出结果:

y = b

x = a

z = c

因此,dict可以列表生成式也可以使用两个变量生成list

>>>d={'x':'a','y':'b','z':'c'}

>>>[k + '=' + v  for k,v in d.items()]

['y=b','x=a','z=c']

比如:

一个list中的所有字符串变成大写:

>>>L = ['HELLO','WORD']

>>>[s.lower() for s in L]

['hello','word']

生成器:

通过列表生成式,我们可以直接创建一个列表。但是由于内存限制,列表容量肯定是有限的。

当我们创建一个包含100万个元素的列表,若我们仅仅访问前面几个元素,那么后面绝大多数元素占用的空间都浪费了。

如果列表元素可以按照某种算法推算出来,那我们是否可以在循环过程中不断的推算出后续的元素。这样,我们就不必创见完整的list,从而节省了大量的空间。

在python中,这种一边循环一边计算的机制,称为生成器:generator

要创建一个generator,有很多种方法:

第一种:只要将列表生成式的[]改成(),就创建了一个generator

>>>g =(x*x for x in range(5))

如果要一个一个的打印出来,可以通过next()函数获得generator的下一个返回值:

>>>next(g)

0

每次调用next(g),就计算出g的下一个元素值,直到计算到最后一个元素,没有更多元素时,就会抛出StopIteration的错误

正确的方法是使用for循环,因为generator也是可迭代的对象:

>>>g =(x*x for x in range(5))

>>>for n in g:

>>>print(n)

02314

定义一个generator的另一个方法。如果一个函数定义包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator。

这里需要理解的是generator和函数的执行流程不一样。

函数的顺序执行,遇到return语句或者最后一行函数语句就返回。

而变成generator的函数,每次调用next()的时候执行,遇到yield语句就返回,再次执行从上次返回的yield语句处继续执行。generator函数的调用,实际返回一个generator对象。

迭代器:

我们知道,可以直接作用于,for循环的数据类型有以下几种:

一类是集合数据类型,如:list,tuple,dict,set,str

一类是generator,包括生成器和带yield的generator function

这些作用于for循环的对象统称为可迭代对象:Iterable

可以使用isinstance()判断一个对象是否是Iterable对象。

>>>from collections import Iterable

>>>isinstance([],Iterable)

True

>>>isinstance({},Iterable)

True

>>>isinstance('abc',Iterable)

True

>>>isinstance((x for x in range(10)),Iterable)

True

>>isinstance(50,Iterable)

False

生成器不但可以作用于for循环,还可以被next()函数调用并返回下一个值,直到最后抛出StopIteration错误异常表示无法继续返回下一个值了。

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator

可以使用isinstance()判断一个对象是否Iterator对象

>>>from collections import Iterable

>>>isinstance([],Iterable)

False

>>>isinstance({},Iterable)

False

>>>isinstance('abc',Iterable)

False

>>>isinstance((x for x in range(10)),Iterable)

True

生成器都是Iterator对象,但list、dict、str虽然是Iteratble,却不是Iterator。

把list、dict、str等变成Iterator可以使用iter()函数:

>>>isinstance(iter([]),Iterable)

True

>>>isinstance(iter({}),Iterable)

True

>>>isinstance(iter('abc'),Iterable)

True

为什么list,dict,str等数据类型不是Iterator?

这是因为Python的Iterator对象表示我一个数据流,甚至可以表示一个无限大的数据流,例如:自然数,而list是永远不可能全体自然数的。

小结:

凡是可以作用于for循环的对象都是Iterable类型;

凡是可作用于next()函数的对象都是Iterator,它们表示的是一个惰性计算的序列

集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得Iterator对象

Python的for循环本质上就是通过不断调用next()函数实现的

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/840445.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号