Python20-Day04
##########迭代器、生成器和面向过程编程##########
一、迭代器
迭代器是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值;
l = [1,2,3]
count = 0
while count < len(l):
print(l[count])
count+=1
为何要有迭代器?
对于序列类型:字符串,列表,元组,可以通过使用索引的方式迭代取出其包含的元素,但是对于字典,集合文件等类型是没有索引的,若还想取出其内部包含的元素,
就必须使用不依赖于索引的迭代方式---迭代器。
什么是可迭代对象?
可迭代的对象指的是内置有__iter__方法的对象,即obj.__iter__,如下:
'hello'.__iter__
(1,2,3).__iter__
[1,2,3].__iter__
{'a':1}.__iter__
{'a','b'}.__iter__
open('a.txt').__iter__
什么是迭代器对象?
可迭代对象执行obj.__iter__()得到的结果就是迭代器对象
而迭代器器对象指的是内置有__iter__又内置有__next__方法的对象
文件类型是迭代器对象:
open('a.txt').__iter__()
open('b.txt').__next__()
注意:
迭代器对象一定是可迭代对象,而可迭代对象不一定是迭代器对象。
迭代器对象的使用
dic={'a':1,'b':2,'c':3}
# iter_dic = dic.__iter__() #得到迭代器对象,迭代器对象既有__iter__又有__next__。
# print(iter_dic.__iter__() is iter_dic) #True 迭代器.__iter__()得到的仍然是迭代器本身
# print(iter_dic.__next__()) #等同于next(iter_dic)
# print(iter_dic.__next__())
# print(iter_dic.__next__())
# print(iter_dic.__next__()) #元素迭代完成,会抛出异常StopIteration #有了迭代器,就可以不依赖索引迭代取值了 需要自己捕捉异常,控制next。
iter_dic = dic.__iter__()
print(iter_dic)
while 1:
try:
k = next(iter_dic)
print(dic[k])
except StopIteration:
break
for循环
dic={'a':1,'b':2,'c':3}
for key in dic:
print(key,dic[key])
#基于for循环,可以不再依赖索引取值
#for循环的工作原理:
1. 执行in后对象的dic.__iter__(),得到一个迭代器对象iter_dic
2. 执行next(iter_dic),将得到的值赋值给k,然后执行循环体代码
3. 重复过程2,直到捕捉到异常StopIteration
迭代器的优缺点:
优点:
- 提供一种统一的不依赖于索引的迭代方式
- 惰性计算,节省内存
缺点:
- 无法获取长度(只有在next完毕才知道到底有几个值)
- 一次性的,只能往后走,不能往前退
二、生成器
什么是生成器?
只要函数内部包含有yield关键字,那么函数名()得到的结果就是生成器,并且不会执行函数内部代码。
def func():
print('====>first')
yield 1
print('====>second')
yield 2
print('====>third')
yield 3
print('====>end') print(func())
# g=func()
# print(g)
# print(next(g))
# print(next(g))
# print(next(g))
# print(next(g))
生成器就是迭代器
g.__iter__
g.__next__
res = next(g)
print(res)
练习题:1、自定义函数模拟range(1,7,2)
#1、自定义函数模拟range(1,7,2)
def my_range(start,stop,step=1):
while True:
if start < stop:
yield start
start+=step
g = my_range(1,7,2) #g为生成器 生成器就是迭代器,可以通过迭代器迭代取值
print(next(g))
print(next(g))
print(next(g))
# for i in my_range(1,7,2): #也可以通过for循环取值
# print(i)
2、模拟管道,实现功能:tail -f access.log | grep '404'
import time
def tail(filepath):
with open(filepath,'rb') as f:
f.seek(0,2)
while True:
line = f.readline()
if line:
yield line
else:
time.sleep(0.2)
def grep(parttern,lines):
for line in lines:
line = line.decode('utf-8')
if parttern in line:
yield line for line in grep('',tail('access.log')):
print(line,end='')
三、yield总结
#1、把函数做成迭代器
#2、对比return,可以返回多次值,可以挂起/保存函数的运行状态
四、面向过程编程
#1、强调:面向过程编程绝对不是用函数编程,面向过程是一种编程思想、思路,而编程思路是不依赖于具体的语言或者语法的。也可以说即使我们不依赖于函数,也可以基于面向过程的思想编写程序
#2、定义
面向过程的核心是过程,过程指的是解决问题的步骤,即先干什么后干什么。
基于面向过程设计程序就好比是设计一条流水线,是一种机械式的思维方式
#3、优点
复杂的问题流程化,进而简单化
#4、缺点
可扩展性差,修改流水线的任意一个阶段,都会牵一发而动全身
#5、应用
扩展性要求不高的场景,典型案例Linux内核
##########三元表达式、列表推导式、生成器表达式、递归、匿名函数、内置函数##########
一、三元表达式、列表推导式、生成器表达式
1、三元表达式
name = input('姓名:> ').strip()
res = 'NB' if name == 'alex' else 'TNB'
print(res)
2、列表推导式
# egg_list = []
# for i in range(1,10):
# egg_list.append('鸡蛋%s' %i)
# print(egg_list) egg_list = ['鸡蛋%s' %i for i in range(1,10)]
print(egg_list)
3、生成器表达式
#1、把列表推导式的[]换成()就是生成器表达式
chicken = ('鸡蛋%s' %i for i in range(1,5))
print(chicken) #chicken = <generator object <genexpr> at 0x00000000021768E0> # print(next(chicken)) #鸡蛋1
# print(next(chicken)) #鸡蛋2
# print(next(chicken)) #鸡蛋3 print(list(chicken)) #['鸡蛋1', '鸡蛋2', '鸡蛋3', '鸡蛋4', ] 因为chicken可迭代,因而可以转换成列表
#2、优点:省内存,一次只产生一个值在内存中
二、声明式编程练习题
#1、将names=['egon','alex_sb','wupeiqi','yuanhao']中的名字全部变大写
names=['egon','alex_sb','wupeiqi','yuanhao'] res = [name.upper() for name in names]
print(res) #['EGON', 'ALEX_SB', 'WUPEIQI', 'YUANHAO']
#2、将names=['egon','alex_sb','wupeiqi','yuanhao']中以sb结尾的名字过滤掉,然后保存剩下的名字长度
names=['egon','alex_sb','wupeiqi','yuanhao']
# res = [name for name in names if 'sb' not in name] #以sb结尾的名字过滤掉 res = ['egon', 'wupeiqi', 'yuanhao']
res = [len(name) for name in names if 'sb' not in name] #[4, 7, 7]
print(res)
#3、求文件a.txt中最长的行的长度(长度按字符个数算,需要使用max函数)
#笨方法
# num_list=[]
# with open('a.txt','r',encoding='utf-8') as f:
# lines = f.readlines()
# for line in lines:
# num_list.append(len(line))
# print(max(num_list))
#声明式方法
with open('a.txt',encoding='utf-8') as f:
print(max(len(line)for line in f))
三、内置函数
现阶段需要掌握的:
divmod
python divmod()函数把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b,a % b)
>>> divmod(7,2)
(3, 1)
>>> divmod(8,2)
(4, 0)
enumerate
enumerate是用来遍历可迭代容器中的元素,同时通过一个计数器变量记录当前元素所对应的索引值。
#示例:
names = ['Bob', 'Alice', 'Guido']
for index, value in enumerate(names):
print(f'{index}: {value}')
#输入如下内容:
0: Bob
1: Alice
2: Guido
这个循环遍历了name列表的所有元素,并通过增加从零开始的计数器变量为每个元素生成索引。
enumerate()函数允许为循环自定义起始索引值。enumerate()函数中接收一个可选参数,该参数允许为本次循环中的计数器变量设置初始值。
names = ['Bob', 'Alice', 'Guido']
for index, value in enumerate(names, 1):
print(f'{index}: {value}')
1: Bob
2: Alice
3: Guido
enumerate是Python的一个内置函数。你应该充分利用它通过循环迭代自动生成的索引变量。
索引值默认从0开始,但也可以将其设置为任何整数。
enumerate函数是从2.3版本开始被添加到Python中的,详情见PEP279。
Python的enumerate函数可以帮助你编写出更加Pythonic和地道的循环结构,避免使用笨重且容易出错的手动生成索引。
为了充分利用enumerate的特性,一定要研究Python的迭代器和数据结构解包功能。 作者:vimiix
链接:https://juejin.im/post/5a31146251882503eb4b4755
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
eval
功能:将字符串str当成有效的表达式来求值并返回结果。
参数:
source : 一个python表达式或者函数compile()返回的代码对象
globals : 可选,必须是dictionary
locals : 可选,任意map对象
可以把list,tuple,dict和string相互转化。
#################################################
字符串转换成列表
>>>a = "[[1,2], [3,4], [5,6], [7,8], [9,0]]"
>>>type(a)
<type 'str'>
>>> b = eval(a)
>>> print b
[[1, 2], [3, 4], [5, 6], [7, 8], [9, 0]]
>>> type(b)
<type 'list'>
#################################################
字符串转换成字典
>>> a = "{1: 'a', 2: 'b'}"
>>> type(a)
<type 'str'>
>>> b = eval(a)
>>> print b
{1: 'a', 2: 'b'}
>>> type(b)
<type 'dict'>
#################################################
字符串转换成元组
>>> a = "([1,2], [3,4], [5,6], [7,8], (9,0))"
>>> type(a)
<type 'str'>
>>> b = eval(a)
>>> print b
([1, 2], [3, 4], [5, 6], [7, 8], (9, 0))
>>> type(b)
<type 'tuple'>
Python20-Day04的更多相关文章
- Spring day04笔记(SVN讲解和回顾昨天知识)
spring day03回顾 事务管理 基于xml配置 1.配置事务管理器 jdbc:DataSourceTransactionManager hibernate:HibernateTransacti ...
- day04 Java Web 开发入门
day04 Java Web 开发入门 1. web 开发相关介绍 2. web 服务器 3. Tomcat服务器启动的问题 4. Tomcat目录结构 5. Web应用程序(虚拟目录映射,缺省web ...
- python day04笔记总结
2019.4.1 S21 day04笔记总结 昨日内容补充 1.解释器/编译器 1.解释型语言.编译型语言 2.解释型:写完代码后提交给解释器,解释器将代码一行行执行.(边接收边解释/实时解释) 常用 ...
- Python基础(函数部分)-day04
写在前面 上课第四天,打卡: 加勒比海盗今天上映:端午节公司发的粽子很有范! 一.函数的基本概念 - 函数是什么? 函数,就是一个'锤子',一个具有特定功能的'锤子',使用者可以在适当的时候使用这个 ...
- day04(权限修饰符,内部类,局部内部类,匿名内部类)
权限修饰符, Public >protected >default > private public 公共权限 随便都可以访问 protected 子类可以访问权限 (子类 ...
- Day04 dom详解及js事件
day04 dom详解 DOM的基础 Document对象 Element对象 Node对象 innerHTML 事件处理 表单验证 上次课内容回顾: JS中ECMAScript用法: JS定义变 ...
- python开发学习-day04(迭代器、生成器、装饰器、二分查找、正则)
s12-20160123-day04 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: ...
- 2017-2018-1 JAVA实验站 冲刺 day04
2017-2018-1 JAVA实验站 冲刺 day04 各个成员今日完成的任务 小组成员 今日工作 完成进度 张韵琪 写博客.进行工作总结 100% 齐力锋 找背景音乐 100% 张浩林 游戏操作说 ...
- python s13 day04
1.1 all() 和 any( ) all() any() 0,None,"", [], (),{} #布尔值为0的 列举,None ,空列表,空元祖,空. print( ...
- Java编程基础阶段笔记 day04 Java基础语法(下)
day04 Java基础语法 (下) 笔记Notes要点 switch-case语句注意 switch-case题目(switchTest5) 循环执行顺序 if-else 实现3个整数排序 Stri ...
随机推荐
- 基于AppDomain的"插件式"开发
很多时候,我们都想使用(开发)USB式(热插拔)的应用,例如,开发一个WinForm应用,并且这个WinForm应用能允许开发人员定制扩展插件,又例如,我们可能维护着一个WinService管理系统, ...
- HDU 1171 (01背包问题)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1171 分析: 例如数据 3 10 2 20 1 30 1 获得这样一个降序的数组: ...
- cloudstack agent host Alert 告警处理
今天nagios告警: 172.17.9.76有Alert,看agent的日志有如下: (Agent-Handler-3:null) Connected to the server Lost conn ...
- 关于ISP、IAP、DFU和bootloader
这是嵌入式开发中常用的几个专业术语,其诞生的背景和其具体作用大概如下 在很久很久以前,那是8051单片机流行的时代,做单片机开发都需要一个专用工具,就是单片机的编程器,或者叫烧写器.说“烧”写一点 ...
- 【git2】git+码云+webStrom
在[git1]中介绍了Git的安装.webstrom配置Git和GitHub.GitHub项目上传下载的方法. 这篇将一下在[git1]步骤(一)基础上webstorm配置码云 实现项目的上传下载. ...
- ios宏定义学习
宏简介: 宏是一种批量处理的称谓.一般说来,宏是一种规则或模式,或称语法替换 ,用于说明某一特定输入(通常是字符串)如何根据预定义的规则转换成对应的输出(通常也是字符串).这种替换在预编译时进行,称作 ...
- SQL进阶语法的多表操作
AS别名 多张表联合操作,如果表多,字段名长,不方便阅读.这里我们可以使用 as 关键字来对字段名设置别名. as也可以省略,看个人喜好,在这里我还是支持把 as 写上,这样我们在面对复杂的SQL ...
- package.json常用的字段
package.json中5个字段: name: 包名 今后下载时输入名称 (注意:要与下载的包名不一样) version:版本号 x.x.x 例如 1.2.3 1 大版本:当这个包有巨大内容变化时( ...
- HTML5 drag & drop 拖拽与拖放
关键词: 1. draggable:规定元素是否可拖动的,draggable=true可拖动 2. dataTransfer:拖拽对象用来传递的媒介,使用方式:event.dataTransfer 3 ...
- 第一篇 深入嵌入式之Linux裸机
{ 个人心得: 嵌入式底层重要的是在CPU(各种架构)或SOC基础上,利用u-boot初始化系统,并启动OS,建立实时多任务环境.文件系统等,再根据功能要求设计上层程序:而对硬件的需有足够掌握. } ...