【Python】迭代器/生成器

Python迭代器/生成器******> »转到**思维导图****> »转到博客园**** 1.迭代 1.1什么是迭代: 更新换代(重复)的过程,每次迭代都必须基于上一次的结果 1.2什么是迭代器: 迭代取值的工具 1.3为什么要有迭代器: 迭代器提供了一种不依赖于索引取值的方式 对于序列类型:字符串、列表、元组,我们可以使用索引的方式迭代取出其包含的元素。但对于字典、集合、文件等类型是没有索引的,若还想取出其内部包含的元素,则必须找出一种不依赖于索引的迭代方式,这就是迭代器 1.4什么是可迭代对象: 可迭代对象指的是内置有__iter__方法的对象,即obj.iter 1.5什么是迭代器对象: 可迭代对象执行obj.iter()得到的结果就是迭代器对象。而迭代器对象指的是即内置有__iter__又内置有__next__方法的对象。 1.6注意: 迭代器对象一定是可迭代对象,而可迭代对象不一定是迭代器对象 需要迭代取值的数据类型:字符串str、列表list、元组tuple、字典dict、集合set、文件对象 文件对象执行内置的__iter__之后还是本身 没有任何变化,文件对象本身就是迭代器对象 针对双下线开头双下划线结尾的方法,推荐读:双下+方法名 2.迭代器取值: 迭代器取值 调用__next__ 迭代器对象无论执行多少次__iter__方法得到的还是迭代器对象本身 2.1异常报错StopIteration:取完了 2.2异常处理: while True: try: print(iter_d.__next__()) except StopIteration: print('老母猪生不动了') break 2.3迭代器取值的特点:只能往后依次取,不能后退 2.4迭代器取值的优点: 1.不依赖于索引取值 2.内存中永远只占一份空间,不会导致内存溢出 2.5迭代器取值的缺点: 1.不能够获取指定的元素 2.取完之后会报StopIteration错 3.for循环的本质 1.将in后面的对象调用__iter__转换成迭代器对象 2.调用__next__迭代取值 3.内部有异常捕获StopIteration,当__next__报这个错 自动结束循环 4.生成器 只要函数内部包含有yield关键字,那么函数名()的到的结果就是生成器,并且不会执行函数内部代码 生成器就是迭代器,可以用__next__方法取值 yield后面跟的值就是调用迭代器__next__方法你能得到的值 yield既可以返回一个值也可以返回多个值,并且多个值也是按照元组的形式返回 可以用.send给yield左边的变量传参,但必须先将代码运行至yield才能为期传值 yeild 1.帮你提供了一种自定义生成器方式 2.会帮你将函数的运行状态暂停住 3.可以返回值 yeid与return异同: 相同点:都可以返回值,并且都可以返回多个 不同点:yield可以返回多次值,而return只能返回一次函数立即结束,yield还可以接受外部传入的值 5.生成器表达式 例如:res = (i for i in range(1,10) if i != 4) ...

2019年7月15日 · 1 分钟

【Python】函数

Python函数 »>转到思维导图****> »转到博客园 递归函数 函数在调用阶段直接或间接的又调用自身 如果一个函数在内部调用自身本身,这个函数就是递归函数。 举例 # 举个例子,我们来计算阶乘n! = 1 x 2 x 3 x ... x n,用函数fact(n)表示,可以看出: # fact(n) = n! = 1 x 2 x 3 x ... x (n-1) x n = (n-1)! x n = fact(n-1) x n # 所以,fact(n)可以表示为n x fact(n-1),只有n=1时需要特殊处理。 # 于是,fact(n)用递归的方式写出来就是: def fact(n): if n==1: return 1 return n * fact(n - 1) # 如果我们计算fact(5),可以根据函数定义看到计算过程如下: ===> fact(5) ===> 5 * fact(4) ===> 5 * (4 * fact(3)) ===> 5 * (4 * (3 * fact(2))) ===> 5 * (4 * (3 * (2 * fact(1)))) ===> 5 * (4 * (3 * (2 * 1))) ===> 5 * (4 * (3 * 2)) ===> 5 * (4 * 6) ===> 5 * 24 ===> 120 扩展 import sys ...

2019年7月12日 · 3 分钟

【Python】装饰器

Python装饰器> »转到****思维导图********> »转到博客园 闭包函数 1.定义在函数内部的函数 2.内部函数内部函数引用了外部函数名称空间作用域的名字 只要满足以上两点都叫做闭包函数 def func(): name = jason' # 先在内部找name没有再往上层找 有了就停止查找 def inner(): print(name) # 现在内部找name没有再往上层找 return inner f = func() # f获取到的是inner的内存地址 f() # 相当于执行 inner() # 函数在定义阶段名字的查找孙旭就已经固定死了,不会因为函数调用位置的变化而变化 给函数传参的两种方式 1.直接传参 def index(name): print(name) 2.闭包 def outter(name): # name = 'jason' def index(): print(name) return index 装饰器 器:就是一个工具 装饰:就是给被装饰对象添加新的功能 开放封闭原则: 开放:对扩展开放 封闭:对修改封闭 装饰器(可调用对象)必须遵循的两个原则: 1.不改变被装饰对象的源代码 2.不改变被装饰对象(可调用对象)调用方法 可调用:callable def new(): print('这是原始函数') def outter(func): def inner(): print('这是内部函数,这里可以加新功能') func() # 这里的func是你想调用的最原始的函数的内存地址,加上()直接调用 print('这是内部函数,这里可以加新功能') return inner # 这里不加括号 返回的是inner函数的内存地址 new = outter(new) # 括号内的new指向的是最原始的new函数的内存地址,前面的new获取的是outter函数的返回值,返回值我们自定义了返回 inner函数的内存地址 # 总结:前面的new获取的是inner的内存地址,后面括号内的new指向的就是最原始的new的内存地址 new() 扩展:import time ...

2019年7月12日 · 2 分钟

【Python】名称空间与作用域/函数的嵌套

Python名称空间与作用域/函数的嵌套** »>转到**思维导图********> »转到****博客园 命名关键字参数 在函数定义阶段,写在*和**可变长参数之间的形参 在给命名关键字参数传值的时候,只能用关键字为期传值 在定义阶段 给你感觉好像是z是默认值参数,放在了m这个位置参数的前面了,应该报错 其实z和m都是命名关键字参数,不是默认值参数和位置参数 def func(x,y=1,*args,z=3,m,**kwargs): print(x,y) print(args) print(z,m) print(kwargs) func(1,2,1,2,3,4,5,6,7,78,8,9,0,z=69,m=999,o=666999,l = 999666) 函数对象 函数是第一类对象:函数名指向的值可以被当中的参数传递 1.函数名可以被传递 name = 'jason' x = name print(x) print(id(x)) def func(): print('from func') # print(func) print(id(func)) f = func func() print(f) f() # 其实指向的也是函数func指向函数体代码的内存地址 2.函数名可以被党组参数传递给其他函数 def func(): print('from func') def index(args): print(args) args() print('from index') # index(1) index(func) 3.函数名可以被当做函数的返回值 def index(): print('index') def func(): print('func') return index res = func() print(res) res() 4.函数名可以被当做容器类型的参数 ...

2019年7月10日 · 2 分钟

【Python】函数

Python函数 > »转到思维导图********> »转到博客园**************** 函数的返回值 函数内要想返回给调用者值 必须用关键字return 不写return:函数默认返回None def func(): print('hahaha') res = func() print(res) 只写return:return除了可以返回值之外,还可以直接结束整个函数的运行 只写return 返回的也是None(None就表示什么都没有) 只写return 返回的也是None(None就表示什么都没有) def func(): l = ['jason','egon','tank'] while True: for i in l: if i == 'egon': # 当i为egon的时候 直接结束函数运行 # break return # print('asdasdkljlsjadl') # 这一行代码拥有都不会运行 print(i) res = func() print(res) 写return None:跟上面的只写return是一样的 def func(): return None res = func() print(res) 写return返回一个值:这个值可以是python任意数据类型 def func(): return '123' def func1(): return [1,2,3] def func2(): return {'name':'jason'} def func3(): return (1,) def func4(): return {1,2,3,4,5} def func5(): return True print(func(),func1(),func2(),func3(),func4(),func5()) 写return返回多个值:return会自动将多个值以元组的形式返回给调用者 ...

2019年7月9日 · 3 分钟

【Python】文件操作/函数前戏

Python文件操作/函数前戏 »>转到思维导图********> »转到博客园**** 文件操作模式补充 "+" 表示可以同时读写某个文件 r+, 读写【可读,可写】 w+,写读【可读,可写】 a+, 写读【可读,可写】 文件内光标移动 一: read(3): 1. 文件打开方式为文本模式时,代表读取3个字符 2. 文件打开方式为b模式时,代表读取3个字节 二: 其余的文件内光标移动都是以字节为单位如seek,tell,truncate 注意: 1. seek有三种移动方式0,1,2,其中1和2必须在b模式下进行,但无论哪种模式,都是以bytes为单位移动的 2. truncate是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate要在r+或a或a+等模式下测试效果 检测文件内容 with open(r'test01.txt','rb') as f: # 先将光标移动到文件末尾 f.seek(0,2) while True: res = f.readline() # 查看光标移动了多少位 bytes # print(f.tell()) if res: print("新增的文件内容:%s"%res.decode('utf-8')) # 说明有人操作当前文件 # else: # # 说明文件没有被任何人操作 # print('暂无其他人操作该文件') 截断文件 with open(r'test','a',encoding='utf-8') as f: f.truncate(6) # 接收的字节的长度 整型 # 保留0~6字节数 后面的全部删除(截断) 修改文件 ...

2019年7月8日 · 1 分钟

【Python】字符编码/文件操作

Python字符编码/文件操作 »>转到思维导图****> »转到博客园**** 字符编码 # 字符编码针对的是文字。 # 字符编码只跟文本文件有关。 # 文本编辑器的输入和输出是两个过程。 # 字符编码表就是字符与数字的对应关系 ASCII码表 用八位二进制表示一个英文字符 GBK 用2Bytes表示一个中文字符,还是用1Bytes表示一个英文字母。最多能表示65535个字符 Unicode万国码 统一用2Bytes表示所有的字符 1.浪费存储空间 2.IO次数增加,程序运行效率降低(致命) # 当内存中的unicode编码格式数据存到硬盘的时候,会按照utf-8编码 # 会将unicode的英文字符由原来的2Bytes变成1Bytes # 会将unicode中文字符由原来的2Bytes变成3Bytes # 现在的计算机内存都是unicode,硬盘都是utf-8 unicode的两个特点 1.用户在输入的时候,无论输什么字符都能够兼容万国字符 2.其他国家编码的数据由硬盘读到内存的时候unicode与其他各个国家的编码都有对应关系 # 数据由内存保存到硬盘 内存中的unicode格式二进制数字 >>>编码(encode)>>>utf-8格式的二进制数据 # 硬盘中的数据由硬盘读到内存 硬盘中的utf-8格式的二进制数据>>>解码(decode)>>>内存中unicode格式的二进制数据 # 保证不乱码在于文本文件以什么编码编的就以什么编码解 # python2将py文件按照文本文件读入解释器中默认使用ASCII码 # python3将py文件按照文本文件读入解释器中默认使用utf-8 # 文件头 # coding:utf-8 因为所有的编码都支持英文字符,所以文件头才能够正常生效 # python3中字符串默认就是unicode编码格式的二进制数 # pycharm终端用的是utf-8格式,windows终端采用的是gbk格式。 encode() # 将unicode编码成可以存储和传输的utf-8的二进制数据 # bytes类型 字节串类型 你就把它当成二进制数据即可 decode() # 将硬盘中的utf-8格式的二进制数据解码成unicode格式的二进制数据 x = '上' res1 = x.encode('gbk') # 将unicode编码成可以存储和传输的utf-8的二进制数据 print(res1) # b'\xe4\xb8\x8a' # bytes类型 字节串类型 你就把它当成二进制数据即可 res2 = res1.decode('gbk') # 将硬盘中的utf-8格式的二进制数据解码成unicode格式的二进制数据 print(res2) # 补充: # 你a他 # 1Bytes|1Bytes|1Bytes|1Bytes|1Bytes|1Bytes|1Bytes # 1+7bit|1+7bit|1+7bit|1+7bit|1+7bit|1+7bit|1+7bit 文件处理 ...

2019年7月5日 · 1 分钟

【Python】列表/字典/元组/集合

Python列表/字典/元组/集合 »>转到思维导图********> »转到博客园**** 列表list count()用来统计列表某个元素的个数 >>> l = [1,2,3,4,5,6,7] >>> res = l.count(8) >>> print(res) 0 clear()用来清除列表元素 >>> res = l.clear() >>> print(res) None >>> print(l) [] reverse()用来将列表反转 >>> l = [1,2,3,4,5,6,7] >>> print(id(l)) 2271674158920 >>> l.reverse() >>> print(l) [7, 6, 5, 4, 3, 2, 1] >>> print(id(l)) 2271674158920 sort()按升序将列表元素排序 >>> l.sort() >>> print(l) [1, 2, 3, 4, 5, 6, 7] >>> print(id(l)) 2271674158920 队列:先进先出 ...

2019年7月4日 · 4 分钟

【Python】数据类型

Python数据类型 »>转到思维导图> »转到博客园**** 整型(int) 用途:记录QQ号、手机号、身份证号等 定义:age = 18 常用操作+内置的方法 int只能转存数字的字符串,小数点都不行 进制转换 >>> print(int('1100',2)) # 二进制转十进制 0,1 12 >>> print(int('14',8)) # 八进制转十进制 0-7 12 >>> print(int('c',16)) # 十六进制转十进制 0-9 A-F 12 # int可以传第一个参数,表示的是第一个参数到底是什么进制 然后转成十进制 >>> print(bin(12)) # 10进制转二进制 0b1100 # 0b1100 0b表示后面的数字是二进制数 >>> print(oct(12)) # 10进制转八进制 0o14 # 0o14 0o表示后面的数字是八进制数 >>> print(hex(12)) # 10进制转16进制 0xc # 0xc 0x表示后面的数字是十六进制数 有序:但凡有索引的数据都是有序的 不可变:值改变的情况下,id一定变 浮点型(float) 用途:记录薪资、身高、体重等 定义: salary = 1.1 # salary = float(1.1) >>> res = float('1.11') >>> print(type(res)) <class 'float'> 有序:但凡有索引的数据都是有序的 ...

2019年7月3日 · 5 分钟

【Python】流程控制

Python流程控制 »>转到思维导图****> »转到博客园******** if判断 判断失误的对错,真假,是否可行 固定语法 if 条件: 代码1 代码2 代码3 代码4 ... python的缩进表示代码的归属 同一缩进的代码,称之为代码块 补充:布尔值位False数据由哪些:0,None,’ ‘,[ ],{ } 布尔值也可以直接用来判断 变量名也可以用来判断,因为变量名指向的值对应的就是True或False else 语法 # 不能单独使用,必须和if,while,for配合使用 if 条件: 代码1 代码2 代码3 代码4 ... else: # 不能单独使用,必须和if,while,for配合使用 代码1 代码2 代码3 代码4 ... if elif else 语法 :同一级别配合使用的时候,只会指向一个代码块 if 条件: 代码1 代码2 代码3 代码4 ... elif 条件: 代码1 代码2 代码3 代码4 ... else: # 不能单独使用,必须和if,while,for配合使用 代码1 代码2 代码3 代码4 ... 走了if就不会走elif else,走了elif就不会走else,if看到没走,走了else说明if elif都没走,都不满足if elif的条件 ...

2019年7月2日 · 1 分钟