Python —— 函数高级特性(切片、迭代、列表生成式、生成器、迭代器)
一、切片(Slice)
在很多编程语言中,针对字符串提供了很多截取函数(i.e. substring),目的就是对字符串切片。python中没有针对字符串的截取函数,需要通过“切片”来完成。
取一个list或tuple的部分元素可以用切片
格式: 假定list或tuple组成的元素组名为m
m[起始值:终止值:步长]
说明:
a. 起始值如果是0,可以省略,但是中间的冒号(:)一定要带上
b. 起始值,终止值限定的是索引范围。
c. 如果从前面开始取数,那么索引时不包括索引[终止值],因为索引时下标从0开始。
d. 如果从后面开始取数,即倒数,如果m[-2:] 则取最后两个元素,如果m[-2:-1]则取倒数第二个元素,注意两者的区别。
e. 不管从前面开始或从后面开始取数,最终取的元素个数为都为终止值-起始值。
python支持m[-1]取倒数第一个元素,那么它同样支持倒数切片。
tuple也可以用切片操作,操作结果仍是tuple。
字符串也可以用切片操作,只是操作结果仍是字符串。字符串'xxx'也可以看成一种list,每个元素就是一个字符。
二、迭代
一个对象,可以通过for循环来遍历这个对象,这种遍历称为迭代。
可迭代对象:list, tuple,字典dict,字符串,生成器generator
1、如何判断一个对象是可迭代对象呢?方法:通过collections模块的Iterable类型判断;
from collections import Iterable
print(isinstance('abd',Iterable)) #字符串是否可迭代 print(isinstance([1,2,4],Iterable)) #list是否可迭代 print(isinstance(123,Iterable)) #整数是否可迭代
下面为在命令交互行测试代码:
在Python中,只要是可迭代对象,无论有无下标,都可以迭代,例如,list和tuple有下标,字典dict没有下标
2、字典dict迭代
默认情况下,dict迭代的是key,for key in d.keys( ) 或 for k in d.keys( )
如果要迭代value,可以用for value in d.values( ) 或 for v in d.values( )
如果要同时迭代key和value,可以用for k, v in d.items( ).
下面是使用代码:
d={'a':1,'b':2,'c':3} #这是一个dict
for key in d: # 遍历key,由于默认是key,所以 in d,如果默认不是key,就需要写成 in d.keys
print(key)
for value in d.values(): #遍历每一个值
print(value)
# 遍历每一个值,这个跟上面的效果是一样的,只不过上面是value,这个是v,这都可以,
# for 和in 中间使用value,那么print中也要用value,不能使用v,要保持一致
for v in d.values():
print(v)
for k,v in d.items(): #遍历key和值
print(k,v)
3、字符串也是可迭代对象,因此,也可作用于for 循环:
for ch in 'abdf':
print(ch)
综上,当我们使用for循环时,只要作用的对象是一个可迭代对象,for循环就可以正常运行,而不必关心该对象是list还是其他数据类型。
4、在Python中实现类似JAVA那样的下标循环,要怎么做?
enumerate( )函数
可以把一个list变成索引-元素对,因此在for循环中可以同时迭代索引和元素本身。
#python内置的enumerate函数可以把一个list变成索引-元素对,
#这样就可以在for循环中同时迭代索引和元素本身
for i, value in enumerate(['a','b','c']):
print(i,value)
Python的for循环里,同时引用两个变量是很常见的,代码如下:
for x, y in [(1,1),(2,3),(3,9)]:
print(x,y)
迭代小结
1、Python中迭代是通过for ……in 来完成的,C语言和JAVA迭代list是通过for循环实现的。
2、Python的for循环抽象程度高于C的for循环,因为Python的for循环不仅可以用在list或tuple上,还可以作用在其他可迭代对象上。
3、enumerate函数把一个list变成索引-元素对
三、列表生成式
是Python内置的可以用来创建list的生成式。
使用方法: 前面一部分是对元素进行的操作,最后面一部分是对元素进行判断
print([x*x for x in [1,2,3,4,5]]) print([x*x for x in range(1,11)]) print([x*x for x in range(1,11) if x % 2 == 0 ]) print([m+n for m in 'ABC' for n in 'XYZ'])
实例:列出当前目录下的所有文件和目录名
import os # 导入os模块
print([d for d in os.listdir('.')])
实例:把list中所有的字符串变成小写
L=['hello','world','IBM','Apple']
print([s.lower() for s in L])
注意:s.lower()中的括号一定要带上,否则会报错
列表生成式练习题目:把一个list中的所有字符串变成小写。
思路: 如果list中既包含字符串,又包含数字,由于非字符串类型没有Lower()方法,所以列表生成式会报错:
L1=['Hello','World',18,'Apple']
print([s.lower() for s in L1 ])
报错信息:
可以使用isinstance()函数判断一个变量是不是字符串,下面为修改后并测试成功的代码:
L1=['Hello','World',18,'Apple']
print([s.lower() for s in L1 if isinstance(s,str) == True])
四、生成器generator
如果列表元素可以按照某种算法推算出来,那我们因此可以在循环的过程中不断推算出后续的元素,这样就不必创建完整的list,从而节省大量的空间。
在Python中,这种一边循环 一边计算的机制,称为生成器:generator。
创建generator的方法
(1)把一个列表生成式的中括号[ ]改成小括号( ),就创建了一个generator。
#这个是创建list
L=[x*x for x in range(10)]
print(L)
#这个是创建生成器generator,使用的是小括号
g=(x*x for x in range(10))
print(g)
(2)创建generator方法:yield关键字
generator保存的是算法,如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现。
如果一个函数定义中包含了yield关键字,那么这个函数就不再是一个普通函数,而是一个generator。
注意:这里最难理解的是,generator和函数的执行流程不一样。
函数是顺序执行,遇到return语句或者最后一行函数语句就返回。
而generator函数,在每次调用next( )的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
定义完一个generator后 ,当调用该generator时,首先要生成一个generator对象,然后才能使用next( )函数不断获得下一个返回值。
生成器generator中如何访问每个元素?
>>>方法一: NEXT()函数
注意:每次调用next( g ),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多元素时,抛出StopIteration的错误。
>>>方法二:For循环
因为通过Next( )函数太繁琐了,而且generator也是可迭代对象(Iterable),所以可以使用for循环来访问每个元素:
g=(x*x for x in range(10))
for n in g:
print(n)
案例解析:获得生成器中的return返回值
def odd():
print('step 1')
yield 1
print('step 2')
yield(3)
print('step 3')
yield(5)
return 'done'
c=odd()
while True:
try:
# i=next(c)
# print(i) #i=next(c),print(i)这两句的效果和print(next(c))的效果相同,都是通过next函数访问每个元素
# print(next(c)) #next函数访问元素时,当取到最后一个元素,再继续往下取时,就会报错,此时会跳转到except语句处执行
#所以上面使用next函数访问的两种方法都会跳转到except语句处,获得return语句的返回值
for i in c: #使用for循环时,不会跳转到except语句处,所以拿不到定义的generator中的return语句的返回值
print(i)
except StopIteration as e:
print("Generator return value:",e.value)
break
左边是next函数运行返回的结果,右边是for循环的结果,只有next函数返回了return语句中的返回值
案例解析:斐波那契数列
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'done' print("下面展示三种访问生成器元素的方式:")
print("通过for循环访问元素:")
for i in fib(6):
print(i) print("通过next函数访问元素:")
o=fib(6) #这相当于先生成一个generator对象,然后使用next函数调用每一个元素
print(next(o))
print(next(o))
print(next(o))
print(next(o))
print(next(o))
print(next(o)) print("通过fib(6)访问元素:") #通过next(fib(6))访问,相当于每次调用next时都是调用一个新的生成器generator
print(next(fib(6)))
print(next(fib(6)))
print(next(fib(6)))
print(next(fib(6)))
print(next(fib(6)))
print(next(fib(6))) print("获得return返回值的访问方式:")
g=fib(6)
while True:
try:
print("g:",next(g))
except StopIteration as e:
print("Generator return value:",e.value)
break
上面展示了不同方法的运行结果:
生成器generator的小结:
1、使用类似列表生成式创建generator时,注意是小括号。
2、使用函数创建generator时,函数定义中要有yield关键字。
3、generator保存的是算法。
4、访问generator中的每个元素:next( )或for循环
5、generator是可迭代对象Iterable
6、每次调用next( g ),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多元素时,抛出StopIteration的错误。
当创建一个generator后,基本上不会调用next( ),而是通过for循环来迭代它,并且不需要关心StopIteration的错误。
五、迭代器
可直接作用于for循环的对象统称为可迭代对象:Iterable.
可直接作用于for循环的数据类型有:
第一类是集合数据类型,如list, tuple, dict, set, str等。
第二类是generator, 包括生成器和带 yield 的generator function.
迭代器( Iterator )的定义:
可被next( )函数调用并不断返回下一个值的对象称为迭代器:Iterator.
注意:可迭代对象和迭代器都是指对象
isinstance( )函数:
使用isinstance( )函数来判断一个对象是否是Iterable对象或Iterator对象。
iter( )函数:
生成器都是Iterator对象,但list, dict, str虽然是Iterable,却不是Iterator。可以使用iter( )函数把list, dict, str等Iterable转换成Iterator。
下面使用next也可以遍历list中每一个元素:
1 it=iter([1,2,3,4,5,6])
2 print(next(it))
3 print(next(it))
4 print(next(it))
5 print(next(it))
6 print(next(it))
在命令交互行模式下测试:
为什么list, dict, str等数据类型不是Iterator?
这是因为Iterator对象表示的是一个数据流,Iterator对象可以被next( )函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能通过next( )函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。
Iterator甚至可以表示一个无限大的数据流,i.e. 全体自然数,而使用list是永远不可能存储全体自然数的。
小结
1、凡是可作用于for循环的对象都是Iterable类型
2、凡是可作用于next( )函数的对象都是Iterator类型,它们表示一个惰性计算的序列
3、列表list、字典dict、字符串str都是Iterable类型但不是Iterator类型,不过可以通过iter( )函数进行转换
4、Python的for循环本质上就是通过不断调用next( )函数实现的
参考:廖雪峰的官方网站:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/00143178254193589df9c612d2449618ea460e7a672a366000
Python —— 函数高级特性(切片、迭代、列表生成式、生成器、迭代器)的更多相关文章
- python高级特性:切片/迭代/列表生成式/生成器
廖雪峰老师的教程上学来的,地址:python高级特性 下面以几个具体示例演示用法: 一.切片 1.1 利用切片实现trim def trim(s): while s[:1] == " &qu ...
- Python学习 Day 4 函数 切片 迭代 列表生成式 生成器
定义函数 def my_abs(x):#求绝对值的my_abs函数 if x >= 0: return x else: return –x def nop():#空函数 pass#占位符 参数检 ...
- python函数高级特性
掌握了Python的数据类型.语句.函数,基本可以编写出很多有用的程序了.但是Python中,代码不是越多越好,而是越少越好.代码不是越复杂越好,而是越简单越好.基于这一思想,我们来介绍python中 ...
- Python笔记(九)_切片、列表生成式
切片 mylist[:3] 取前3位元素,0可省略不写 mylist[-4:] 取后4位元素,0可省略不写 mylist[2:4] 从第2个开始取,取到第4个,但第4个不取,取的元素值为4-2=2 m ...
- Python之旅Day5 列表生成式 生成器 迭代器 装饰器
装饰器 器即函数,装饰即修饰,意指为其他函数添加新功能 装饰器定义:本质就是函数,功能是为其他函数添加新功能 装饰器涉及的知识点= 高阶函数+函数嵌套+闭包 在遵循下面两个原则的前提下为被装饰者新功能 ...
- 列表生成式 生成器 迭代器 yield
列表生成式 格式:通过一个或者若干个在List里边的for构建List而非List外部的for循环 举个例子:计算从1到10整数的平方构成一个List L=[ x*x for x in range(1 ...
- python 基础 切片 迭代 列表生成式
对list 进行切片 如列表 L = ['Adam', 'Lisa', 'Bart', 'Paul'] L[0:3] ['Adam', 'Lisa', 'Bart'] L[0:3]表示,从索引0开始取 ...
- python的高级特性:切片,迭代,列表生成式,生成器,迭代器
python的高级特性:切片,迭代,列表生成式,生成器,迭代器 #演示切片 k="abcdefghijklmnopqrstuvwxyz" #取前5个元素 k[0:5] k[:5] ...
- Python 高级特性介绍 - 迭代的99种姿势 与协程
Python 高级特性介绍 - 迭代的99种姿势 与协程 引言 写这个笔记记录一下一点点收获 测试环境版本: Python 3.7.4 (default, Sep 28 2019, 16:39:19) ...
随机推荐
- (.NET高级课程笔记)Lambd、Linq总结
知识总结 1.委托简介:委托是一种类型,可以写在类里,也可以写在类外面,级别和类一样高. 2.匿名方法.匿名类 3.Lambda表达式:goes to 4.系统自带委托:Func/Action 5.扩 ...
- Spring boot 源码分析(前言)
开坑达人 & 断更达人的我又回来了 翻译的坑还没填完,这次再开个新坑= = 嗯,spring boot的源码分析 本坑不打算教你怎么用spring boot = = 也不打算跟你讲这玩意多方便 ...
- javascript学习-基本类型
javascript学习-基本类型 1.概述 javascript的数据类型大体上分两种:基本类型和对象类型.简单的区分就是基本类型是无法再分的原子级类型:对象类型是容器,可以容纳基本类型和对象类型. ...
- WEB学习小笔记
环境基于WIN10.IDEA最新版.JDK1.8.TOMCAT9 下面说的有错的地方希望指出,谢谢. STRUT2 1.在maven下的时候系统会系统创建一个叫做log4j的配置文件,但是到了这个版本 ...
- ES6中的解构赋值
在解释什么是解构赋值前,我们先来看一下, ES5 中对变量的声明和赋值. var str = 'hello word'; 左边一个变量名,右边可以是字符串,数组或对象. ES6 中增加了一种更为便捷的 ...
- DB2数据库常用的函数
1.value函数 语法value(表达式1,表达式2)value函数是用返回一个非空的值,当其第一个参数非空,直接返回该参数的值,如果第一个参数为空,则返回第一个参数的值. eg:表示如果T1.ID ...
- 利用mybatis-generator自动生成代码,发生:Plugin execution not covered by lifecycle configuration后解决方案
1,报错信息 Plugin execution not covered by lifecycle configuration: org.mybatis.generator:mybatis-genera ...
- Hibernate一级缓存和二级缓存详解
(1)一级缓存 是Session级别的缓存,一个Session做了一个查询操作,它会把这个操作的结果放在一级缓存中,如果短时间内这个session(一定要同一个session)又做了同一个操作,那么h ...
- C语言解析WAV音频文件
C语言解析WAV音频文件 代码地址: Github : https://github.com/CasterWx/c-wave-master 目录 前言 了解WAV音频文件 什么是二进制文件 WAV的二 ...
- Swift-Extensions
日常开发中,frame 是我们经常用到的,但是 UIKit 不允许我们直接设置 frame.origin.x frame.origin.y frame.size.wight frame.size.he ...