##########迭代器、生成器和面向过程编程##########

一、迭代器

  迭代器是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值;

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的更多相关文章

  1. Spring day04笔记(SVN讲解和回顾昨天知识)

    spring day03回顾 事务管理 基于xml配置 1.配置事务管理器 jdbc:DataSourceTransactionManager hibernate:HibernateTransacti ...

  2. day04 Java Web 开发入门

    day04 Java Web 开发入门 1. web 开发相关介绍 2. web 服务器 3. Tomcat服务器启动的问题 4. Tomcat目录结构 5. Web应用程序(虚拟目录映射,缺省web ...

  3. python day04笔记总结

    2019.4.1 S21 day04笔记总结 昨日内容补充 1.解释器/编译器 1.解释型语言.编译型语言 2.解释型:写完代码后提交给解释器,解释器将代码一行行执行.(边接收边解释/实时解释) 常用 ...

  4. Python基础(函数部分)-day04

    写在前面 上课第四天,打卡: 加勒比海盗今天上映:端午节公司发的粽子很有范! 一.函数的基本概念 - 函数是什么?  函数,就是一个'锤子',一个具有特定功能的'锤子',使用者可以在适当的时候使用这个 ...

  5. day04(权限修饰符,内部类,局部内部类,匿名内部类)

    权限修饰符, Public  >protected >default > private public 公共权限   随便都可以访问 protected  子类可以访问权限  (子类 ...

  6. Day04 dom详解及js事件

    day04 dom详解 DOM的基础 Document对象 Element对象 Node对象 innerHTML 事件处理 表单验证   上次课内容回顾: JS中ECMAScript用法: JS定义变 ...

  7. python开发学习-day04(迭代器、生成器、装饰器、二分查找、正则)

    s12-20160123-day04 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: ...

  8. 2017-2018-1 JAVA实验站 冲刺 day04

    2017-2018-1 JAVA实验站 冲刺 day04 各个成员今日完成的任务 小组成员 今日工作 完成进度 张韵琪 写博客.进行工作总结 100% 齐力锋 找背景音乐 100% 张浩林 游戏操作说 ...

  9. python s13 day04

    1.1 all() 和 any( )   all() any()   0,None,"", [], (),{} #布尔值为0的 列举,None ,空列表,空元祖,空. print( ...

  10. Java编程基础阶段笔记 day04 Java基础语法(下)

    day04 Java基础语法 (下) 笔记Notes要点 switch-case语句注意 switch-case题目(switchTest5) 循环执行顺序 if-else 实现3个整数排序 Stri ...

随机推荐

  1. Python中乘法

    1.numpy乘法运算中"*"或multiply(),是数组元素逐个计算,具体代码如下: import numpy as np # 2-D array: 2 x 3 two_dim ...

  2. 初识Qt涂鸦板绘制

    1.新建一个Qt Gui应用,项目名称为myPalette,基类选择为QMainWindow,类名设置为MainWindow. 2.在mainwindow.h头文件中添加以下代码,同时添加#inclu ...

  3. 数字电路中应避免产生不必要的锁存器 Latch

    锁存器(Latch)是数字逻辑电路中很重要的一种基本电路,常见的锁存器包括三个端口:数据输入口.数据输出口.使能端.当使能端为高电平时,输入口的数据直接送到输出口,此时输入输出口可以看成是直接连通的: ...

  4. Python学习笔记系列——高阶函数(map/reduce)

    一.map #变量可以指向函数,函数的参数能接受变量,那么一个函数就可以接受另一个函数作为参数,这种函数被称之为高阶函数 def add(x,y,f): return f(x)+f(y) print( ...

  5. 利用SimpleDateFormat进行时间的跨时区转换 - Java

    * 次方法主要用来将特定时区的时间转换成指定时区的时间,比如将北京时间“2018-04-08 15:40:49.031”,转换对应的美国东部时间是“2018-04-08 03:40:49.031”   ...

  6. 【nodeJs】nodejs

    node.js

  7. 【Linux】LVM逻辑卷管理和RAID

    LVM概述: 是对磁盘分区进行管理的一种机制 是一种将一个或多个硬盘的分区在逻辑上集合,相当于一个大硬盘来使用,当硬盘的空间不 够使用的时候,可以继续将其它的硬盘的分区加入其中,这样可以实现一种磁盘空 ...

  8. MongoDB4.0+版本安装

    >>>首先要下载MongoDB软件安装包, MongoDB社区版官网下载 >>>双击msi安装文件进行安装,点击"Next" >>& ...

  9. pg_stat_statements源代码分析

    磨砺技术珠矶,践行数据之道,追求卓越价值 回到上一级页面:PostgreSQL内部结构与源代码研究索引页    回到顶级页面:PostgreSQL索引页 pg_stat_statement的源代码,非 ...

  10. MFC 消息映射、分派和传递

    几个重要的结构体: struct AFX_MSGMAP { AFX_MSGMAP* pBaseMessageMap; AFX_MSGMAP_ENTRY* lpEntries; } struct AFX ...