Python(迭代器 生成器 装饰器 递归 斐波那契数列)
1、迭代器
迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退。另外,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件。
特点:
- 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
- 不能随机访问集合中的某个值 ,只能从头到尾依次访问
- 访问到一半时不能往回退
- 便于循环比较大的数据集合,节省内存
迭代器实例:
name = iter(['chen','a','b','c'])
print(name.__next__())
print(name.__next__())
print(name.__next__())
print(name.__next__())
print(name.__next__()) #最后一次会报错 StopIteration
2、生成器
生成器generator
定义:一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator),如果函数中包含yield语法,那这个函数就会变成生成器
def cash_money(money,num):
while money > 0:
money-=num
yield num,money
print('又来取钱了啊,败家子!!')
atm=cash_money(1000,200)
print('取了%s,还剩下%s'%atm.__next__())
print('取了%s,还剩下%s'%atm.__next__())
print('交个大保健')
print('取了%s,还剩下%s'%atm.__next__())
print('取了%s,还剩下%s'%atm.__next__())
'''
取了200,还剩下800
又来取钱了啊,败家子!!
取了200,还剩下600
交个大保健
又来取钱了啊,败家子!!
取了200,还剩下400
又来取钱了啊,败家子!!
取了200,还剩下200
'''
#这个yield的主要效果呢,就是可以使函数中断,并保存中断状态,中断后,代码可以继续往下执行,过一段时间还可以再重新调用这个函数,从上次yield的下一句开始执行。
另外,还可通过yield实现在单线程的情况下实现并发运算的效果,yield也可以接受参数,入下:
def chi(name,num):
print('%s来买包子,买%s个'%(name,num))
while True:
baozi = yield
print('包子%s来了,被%s吃了'%(baozi,name))
def zuo(name,name2):
A=chi(name,10)
B=chi(name2,10)
A.__next__()
B.__next__()
print('老子开始做包子了')
for i in range(1,20,2):
print('做了两个包子!')
A.send(i)
B.send(i+1)
zuo('陈','邱')
'''
陈来买包子,买10个
邱来买包子,买10个
老子开始做包子了
做了两个包子!
包子1来了,被陈吃了
包子2来了,被邱吃了
做了两个包子!
包子3来了,被陈吃了
包子4来了,被邱吃了
做了两个包子!
包子5来了,被陈吃了
包子6来了,被邱吃了
做了两个包子!
包子7来了,被陈吃了
包子8来了,被邱吃了
做了两个包子!
包子9来了,被陈吃了
包子10来了,被邱吃了
做了两个包子!
包子11来了,被陈吃了
包子12来了,被邱吃了
做了两个包子!
包子13来了,被陈吃了
包子14来了,被邱吃了
做了两个包子!
包子15来了,被陈吃了
包子16来了,被邱吃了
做了两个包子!
包子17来了,被陈吃了
包子18来了,被邱吃了
做了两个包子!
包子19来了,被陈吃了
包子20来了,被邱吃了
'''
3、装饰器
示例1:
def login(func):
if 1==1:
print('passed user verification...')
return func
else:
return aa
def tv(name):
print('欢迎来到%s!'%name)
def aa(aa):
print('aaaaa')
tv = login(tv) #可用@login代替 详看下一示例
tv('Tv')
'''
passed user verification...
欢迎来到Tv!
'''
'''
写代码要遵循开发封闭原则,虽然在这个原则是用的面向对象开发,但是也适用于函数式编程,简单来说,它规定已经实现的功能代码不允许被修改,但可以被扩展,即:
封闭:已实现的功能代码块
开放:对扩展开发'''
示例2: 再此对上述代码进行优化,装饰利用@
def login(func):
def inner(arg):
print('passwd user verification')
func(arg)
return inner
@login #@login = #tv = login(tv)
def tv(name):
print('Welcome %s to tv page!!'%name)
tv('tv') #等同于# login(tv)('tv')
'''
1、用户调用tv('tv')函数,程序检测tv函数上层加有装饰器@login
2、(这里可以吧装饰器@login理解为执行tv函数之前先@login(login说:谁tm艾特我!),就会执行login函数,func的形参func:(tv你小子艾特我干嘛?tv:我要调用你,则func=tv))
3、login函数内部加了一个函数,第一次执行将函数加载到内存,login函数return返回结果为函数inner,此时,调用inner函数,用户执行tv的实参('tv')就传入到了inner的形参里
4、打印密码验证通过,再此可加上判断即可,
5、inner执行验证完成后调用了func(arg),也就是login的形参 也就是tv('tv') ,现在就调用了tv函数,打印出欢迎登陆信息
'''
问题:可以装饰具有处理n个参数的函数的装饰器?
def w1(func):
def inner(*args,**kwargs):
# 验证1
# 验证2
# 验证3
return func(*args,**kwargs)
return inner @w1
def f1(arg1,arg2,arg3): # arg1,arg2,arg3 也可以用*,** 表示
print 'f1'
问题:一个函数可以被多个装饰器装饰吗? YES!顺序为按照装饰器的顺序依次执行
def w1(func):
def inner(*args,**kwargs):
# 验证1
# 验证2
# 验证3
return func(*args,**kwargs)
return inner def w2(func):
def inner(*args,**kwargs):
# 验证1
# 验证2
# 验证3
return func(*args,**kwargs)
return inner @w1
@w2
def f1(arg1,arg2,arg3):
print 'f1'
装饰器+参数
def Before(request,kargs):
print ('before')
# print(Before(1,2))
def After(request,kargs):
print ('after')
def Filter(before_func,after_func):
def outer(main_func):
def wrapper(request,kargs):
before_result = before_func(request,kargs)
# if(before_result != None):
# return before_result;
main_result = main_func(request,kargs)
# if(main_result != None):
# return main_result;
after_result = after_func(request,kargs)
# if(after_result != None):
# return after_result;
return wrapper
return outer
@Filter(Before, After)
def Index(request,kargs):
print ('index')
if __name__ == '__main__':
Index(1,2) #Filter(Before,After)(Index)('1','2') # #号后面的解释纯属个人拆分理解
#outer (Index)('1','2')
#wrapper ('1','2')
#Before(1,2)
#Index(1,2)
#After(1,2)
4、斐波那契数列
斐波那契(前两个数的值相加等于后面的数的值) 例:
斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368def func(arg1,arg2,stop):
List=[]
def func(a,b,c):
if a == 0:
print(a,b)
d=a+b
List.append(d)
if d < c: func(b,d,c)
# print(List)
func(1,2,50)
print(List)
>>> [3, 5, 8, 13, 21, 34, 55]
5、递归
特点
要求
def func(yuan,find):
zhongjian = int(len(yuan) / )
if zhongjian >=:
if yuan[zhongjian] > find:
func(yuan[:zhongjian],find) #func(yuan[:zhongjian],find)
elif yuan[zhongjian] < find:
func(yuan[zhongjian:],find)
else:
print('found find',yuan[zhongjian])
else:
print('no found')
if __name__== '__main__':
data = [, , , , ,, , , , , , , , , , , , , , , , , , , , ]
print(data)
func(data,)
>>> [, , , , , , , , , , , , , , , , , >>>, , , , , , , , ]
>>>found find
2分算法思路:
1、func(data,8)调用函数func 传入的实参为data列表,8
2、执行函数体, 此时zhongjian函数的值就等于列表data的长度/2 , 假设为300
3、进行判断此时yuan长度>=1 数据是否还有值,这里等于设置了2分算法的条件
4、进入判断,原数据的中间值是否比查找的值大, 这里暂定300 > 8 , 因此进入了第一次判断进行的操作
5、再次执行函数func(yuan[:zhongjian],find) 此时函数体里第一个形参就=600[:300] 大于索引往左切片
6、之后进行依次循环 如果循环到yuan[zhongjian] < find 则执行<判断里面的函数体知道判断结束
'''
算法基础
data=[[i for i in range()] for ii in range() ]
for r_index,row in enumerate(data):
for c_index in range(len(row)):
data[r_index][c_index] = row[r_index]
print(data)
>>> [[0, 0, 0, 0], [1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3]]
第二种方法:
data=[[i for i in range()] for ii in range() ]
for r_index,row in enumerate(data):
for c_index in range(r_index,len(row)):
tmp = data[c_index][r_index]
data[c_index][r_index] = row[c_index]
data[r_index][c_index] = tmp
print(data) >>> [[, , , ], [, , , ], [, , , ], [, , , ]]
Python(迭代器 生成器 装饰器 递归 斐波那契数列)的更多相关文章
- Python 迭代器&生成器,装饰器,递归,算法基础:二分查找、二维数组转换,正则表达式,作业:计算器开发
本节大纲 迭代器&生成器 装饰器 基本装饰器 多参数装饰器 递归 算法基础:二分查找.二维数组转换 正则表达式 常用模块学习 作业:计算器开发 实现加减乘除及拓号优先级解析 用户输入 1 - ...
- JS高级. 06 缓存、分析解决递归斐波那契数列、jQuery缓存、沙箱、函数的四种调用方式、call和apply修改函数调用方法
缓存 cache 作用就是将一些常用的数据存储起来 提升性能 cdn //-----------------分析解决递归斐波那契数列<script> //定义一个缓存数组,存储已经计算出来 ...
- Python开发【算法】:斐波那契数列两种时间复杂度
斐波那契数列 概述: 斐波那契数列,又称黄金分割数列,指的是这样一个数列:0.1.1.2.3.5.8.13.21.34.……在数学上,斐波纳契数列以如下被以递归的方法定义:F(0)=0,F(1)=1, ...
- Python初学者笔记:打印出斐波那契数列的前10项
问题:斐波那契数列(意大利语: Successione di Fibonacci),又称黄金分割数列.费波那西数列.费波拿契数.费氏数列,指的是这样一个数列:0.1.1.2.3.5.8.13.21.- ...
- java递归 斐波那契数列递归与非递归实现
递归简单来说就是自己调用自己, 递归构造包括两个部分: 1.定义递归头:什么时候需要调用自身方法,如果没有头,将陷入死循环 2.递归体:调用自身方法干什么 递归是自己调用自己的方法,用条件来判断调用什 ...
- python几个练习(素数、斐波那契数列)
随机输入求素数: x = int(input("please enter the number:")) if x != 1: for i in range(2, x): if x ...
- 4.python迭代器生成器装饰器
容器(container) 容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用in, not in关键字判断元素是否包含在容器中.通常这类数据结构把所有的元素存储在内存中 ...
- Python迭代器&生成器&装饰器
1. 迭代器 1.1 可迭代对象(Iterator) 迭代器协议:某对象必须提供一个__next__()方法,执行方法要么返回迭代中的下一项,要么引起一个Stopiteration异常,以终止迭代(只 ...
- Python迭代器,生成器,装饰器
迭代器 通常来讲从一个对象中依次取出数据,这个过程叫做遍历,这个手段称为迭代(重复执行某一段代码块,并将每一次迭代得到的结果作为下一次迭代的初始值). 可迭代对象(iterable):是指该对象可以被 ...
随机推荐
- LeetCode Rectangle Area (技巧)
题意: 分别给出两个矩形的左下点的坐标和右上点的坐标,求他们覆盖的矩形面积? 思路: 不需要模拟,直接求重叠的部分的长宽就行了.问题是如果无重叠部分,注意将长/宽给置为0. class Solutio ...
- 用 CSS 实现字符串截断
[要求]:如何用css实现字符串截断,超出约定长度后用缩略符...代替? ♪ 答: <html> <head> <meta charset="UTF-8&q ...
- 用Rprofile文件配置打开时R的设置
R中经常会使用一些命令,而且需要重复输入,非常麻烦.如果能够一打开R就直接使用会方便很多. 通过配置一个.Rprofile文件,可以达到我们的目的. 注:本文仅适用于Mac # 创建一个.Rprofi ...
- Linux上的free命令学习
Linux新手,今天使用了free命令来查看电脑内存的使用情况.如下:-m表示以M来显示. 1.基本信息介绍 (1)其中纵向信息: Mem:表示物理内存大小 -/+ buffers/cached:表示 ...
- 设置drawable图片
google官方建议在textView和imageView挨着的时候,建议使用drawable来显示图片 第一个方法:setCompoundDrawablesWithIntrinsicBounds(D ...
- iOS学习笔记---c语言第十天
动态内存分配 一.存储区划分 从低到高(内存地址小----内存地址大) : 代码区---常量区---静态区---堆区---栈区 栈内存 //凡是在函数体内定义的变量 都存储在栈区(包括形参). ; ...
- ANTLR3完全参考指南读书笔记[04]
前言 学习框架或第三方库的方法是什么 (1)少量的浏览manual或tutoral,只关注程序所需的特征,再完善其详细内容和特征的认识? (2)花大量的时间研究详细内容,再考虑程序实现? 这是个先有鸡 ...
- matplotlib example
# This file generates an old version of the matplotlib logofrom __future__ import print_function# Ab ...
- JQuery onload、ready概念介绍及使用方法
页面加载完成有两种事件,一是ready,表示文档结构已经加载完成,onload,ready概念容易混淆,下面为大家详细介绍下 页面加载完成有两种事件,一是ready,表示文档结构已经加载完成(不包 ...
- hdu 2680 最短路径(dijkstra算法+多源最短路径单源化求最小值)这题有点意思
Choose the best route Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...