迭代器 Iterator:
可迭代对象:list tuple dict set frozenset str range() reversed() map() sorted() filter();
迭代器是访问可迭代对象的工具(对象);
1、什么是迭代器:
迭代器是指用iter(obj)函数返回的对象(实例)
迭代器可以用next(it) 函数获取可迭代对象的数据;
2、迭代器相关函数:
iter(iterable) 从可迭代对象中返回一个迭代器,iterable必须是一个能提供一个迭代器的对象;
next(iterator) 从迭代器iterator中获取下一个记录,如果无法获取下一条记录,则触发stopIteration异常通知;
说明:迭代器只能往前取值,不能后退;
示例: L = [2, 3, 4, 5, 7] it = iter(L) #让可迭代对象L提供一个迭代器 next(it) #2 next(it) #3 next(it) #4 next(it) #5 next(it) #7 next(it) #StopIteration 异常通知 #此示意用while语句和迭代器来访问列表 L = [2, 3, 5, 7] it = iter(L) while True: try: x = next(it) except StopIteration: break
生成器 Generator:
1、什么是生成器:
生成器是能够动态提供数据的对象,生成器对象也是可迭代对象;
生成器有两种:
1.生成器函数
2.生成器表达式
2、生成器函数定义:
含有yield语句的函数是生成器函数,此函数被调用将返回一个生成器对象;
注:yield翻译为(产生或生成)
yield语句
语法:
yield 表达式
说明:
1.yield 用于def 函数中,目的是将此函数作为生成器函数使用;
2.yield 用来生成数据,供迭代器的next(it) 函数使用;
3、生成器函数说明:
1.生成器函数的调用将返回一个生成器对象,生成器对象是可迭代对象;
2.生成器函数调用return 会触发一个StopIteration异常;
#yield.py #此示例示意函数yield 语句的生成器函数定义方式和用法 def myyield(): '''此函数因含有yield语句,所以是生成器函数''' print('即将生成1') yield 1 print('即将生成3') yield 3 print('即将生成5') yield 5 print('即将生成7') yield 7 print('即将生成结束') gen = myyield() #gen绑定的是生成器,生成器是可迭代对象 it = iter(gen) #返回迭代器 x = next(it) #next()语句调用时才开始执行生成器函数的语句(如print),直到遇见yield语句停止,我待下次next()语句调用; print(x) print(x) print(next(it)) print(next(it)) print(next(it)) print(next(it))
4、生成器表达式:
语法:
(表达式 for 变量 in 可迭代对象 [if 真值表达式])
说明:
if 子句可以省略
作用:
用推导式的形式生成一个新的生成器;
示例: gen = (x ** 2 for x in range(1, 5)) it = iter(gen) next(it) #1 next(it) #4 next(it) #9 next(it) #16 >>> (x ** 2 for x in range(1, 5)) #注意 生成器数据是现用,现生成 <generator object <genexpr> at 0x00000222A1C796D8> >>> 示例: L = [2, 3, 5, 7] Lst = [x + 1 for x in L] #列表推导式 it = iter(Lst) print('1',next(it)) #3 L[1] = 30 print(L) print('2',next(it)) #4 L = [2, 3, 5, 7] Lst = (x + 1 for x in L) #生成器表达式,不存储数据 it = iter(Lst) print('3',next(it)) #3 L[1] = 30 print(L) print('4',next(it)) #31
迭代工具函数:
作用:
生成一个个性化的可迭代对象
函数名:
zip(iter1, iter2, iter3, .....) 返回一个zip对象,此对象用于生成一个元组,此元组中的元素分别由iter1,iter2可迭代对象中的元组构成(元组个数由最小的可迭代对象决定);
enumerate(iterable, start=0) 生成带索引的枚举对象,返回的迭代类型为索引-值对(index-value)对,默认索引从零开始,也可用start指定; 序号;
#示例: numbers = [10086, 10000, 10010, 95588] names = ['中国移动','中国电信','中国联通'] for t in zip(numbers, names): print(t) for n, a in zip(numbers, names): #注 for 变量列表 in zip(...) 序列赋值 print(a, '的客服号码是', n) for t in zip(range(1000), numbers, names): print(t) for t in enumerate(names): print(t) for t in enumerate(names, 1000): print(t)
#练习 # 写一个程序,读入任意行文字,当输入空行时,结束输入,打印带有行号的输入结果 # 如: # 请输入:hello # 输出如下:# 第1行:hello def read_lines(): L = [] while True: s = input('请输入:') if not s: break L.append(s) return L def print_lines(L): '''打印带有行号的文字信息''' for t in enumerate(lines, 1): print('第%d行:%s' % t) if __name__ == '__main__': lines = read_lines() print_lines(lines)
序列:list, str, tuple, bytes, bytearray
字节串 bytes :(也叫字节序列)
1、字节串bytes
作用:存储以字节为单位的数据
说明:
字节串是不可变的字节序列
字节是0~255的整数(0x00~0xFF; 0b00000000~0b11111111)
创建空字节的字面值:
b = b'' b绑定空字节串
b = b"" b绑定空字节串
b = b'''''' b绑定空字节串
b = b"""""" b绑定空字节串
创建非空字节串的字面值:
b = b'ABCD'
b = b'\x41\x42'
2、字节串的构造函数 bytes:
bytes() 生成一个字的字节串,等同于b'';
bytes(整形可迭代对象) #用可迭代对象初始化一个字节串
bytes(整数n) 生成n个值为0的字符串
bytes(字符串,encoding='utf-8') 用字符串的转换编码生成一个字节串
示例: b = bytes() b = bytes(range(0, 255)) b = bytes(10) b = bytes('你好', 'utf-8') >>> bytes('hello','GBK') #b'hello' >>> bytes('hello','utf-8') #b'hello'
国家标准码:
GBK
GB2312
GB18030
Unicode标准码:
Unicode(utf-8)
3、字节串的运算:a 97 A 65 0 48
+ += * *=
< <= > >= == !=
in / not in
示例 >>> b = b'ABC' + b'123' >>> len(b) #6 >>> b #b'ABC123' >>> max(b) #67 >>> min(b) #49 >>> sum(b) #348 >>> b'abC' > b'abD' #False >>> b'A' in b #True >>> 49 in b #True >>> b[::2] #b'AC2'
4、字节串的索引和切片:
5、字节串的函数:
len(x) max(x) min(x) sum(x) any(x) all(x)
6、字节串bytes 与 字符串str 的区别:
bytes 存储字节(0~255)
str 存储unicode字符(0~65535或更大)
str与bytes转换: 编码(encode) str ----------> bytes b = s.encode(encoding='utf-8') 解码(decode) bytes -------------> str s = b.decode(encoding='utf-8')
help(str.encode) >>> s = 'hello,你好' >>> b = s.encode('utf-8') >>> b #b'hello,\xe4\xbd\xa0\xe5\xa5\xbd' >>> s2 = b.decode('utf-8') >>> s2 #'hello,你好' list ---> tuple set ---> frozenset bytearray----> bytes
字节数组 bytearray:
可变的字节序列;
创建函数 bytearray:
bytearray() 创建字节数组
bytearray(可迭代对象) 同bytes(可迭代对象)
bytearray(整数n)
bytearray(字符串,encoding='utf-8')
>>> ba = bytearray() >>> type(ba) #<class 'bytearray'> >>> ba #bytearray(b'') >>> bytearray(range(65,70)) #bytearray(b'ABCDE') >>> bytearray(10) #含有10字节都为0的字节数组,最大值和最小值都为0; bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
运算操作: + += * *=
比较运算:< <= > >= == !=
in / not in
函数: len(x) max(x) min(x) sum(x) any(x) all(x)
索引 index / 切片 slice:
字节数组支持索引和切片赋值,规则同列表的索引和切片赋值规则;
示例: >>> ba = bytearray(b'ABCDEF') >>> ba bytearray(b'ABCDEF') >>> ba[::2] = [48, 49, 50] >>> ba bytearray(b'0B1D2F') >>> 字节数组的方法: 详见: help(bytearray)
文件 file: (RAM 随机存储器)
文件是用于数据存储的单位;
文件通常用来长期存储数据;
文件中的数据是以字节为单位进行顺序存储的;
1、文件的操作流程:
1. 打开文件
2. 读/写文件
3. 关闭文件
注:任何的操作系统,同一个应用程序同时打开文件的数量有最大数限制,所以在用完文件后需要关闭;
2、文件的打开函数open
open(file, mode='rt') 用于打开一个文件,返回此文件流对象,如果打开文件失败,则会触发OSError错误;
3、文件的关闭方法:
F.close() 关闭文件,释放系统资源;
- 文件常用方法: F.close() 关闭文件(关闭后文件不能再读写会发生ValueError错误) F.readline() 读取一行数据(包括行尾换行符\n), 如果到达文件尾则返回空行 F.readlines(max_chars=-1) 返回每行字符串的列表,max_chars为最大字符(或字节)数, F.writelines(lines) 每行字符串的列表 F.flush() 把写入文件对象的缓存内容写入到磁盘 F.read(size = -1) 从一个文件流中最多读取size个字符 F.write(text) 写一个字符串到文件流中,返回写入的字符数 二进制文件操作方法: F.tell() 返回当前文件流的绝对位置 F.seek(offset, whence=0) 改变数据流的位置,返回新的绝对位置 F.readable() 判断这个文件是否可读,可读返回True,否则返回False F.writable() 判断这个文件是否可写,可写返回True,否则返回False F.seekable() 返回这个文件对象是否支持随机定位 F.truncate(pos = None) 剪掉 自pos位置之后的数据,返回新的文件长度(字节为单位)</td>
4、文本文件操作模式:
模式字符:
't' (默认)
1. 默认文件中存储的数据为字符数据,以行为单位分隔,在python内部统一用'\n'作为换行符进行分隔;
2. 对文本文件的读写需要用字符串(str)进行读取和写入数据;
各操作系统的换行符:
linux 换行符: '\n'
whindows 换行符: '\r\n'
旧的macintosh 换行符: '\r'
新的Mac OS 换行符: '\r'
说明:
在文本文件模块下,各操作系统的换行符在读入python内部时办的为字符'\n';
def read_file_content(): try: f = open('info.txt') while True: s = f.readline() #'小张 20 100\n' if not s: break s2 = s.strip() #去掉两端空白字符(#'小张 20 100') name_age_score = s2.split() #['小张' '20' '100'] n, a, s = name_age_score #序列赋值 d = {'name': n, 'age': int(a), 'score': int(s)} L.append(d) print(s) except OSError: print('打开文件失败') return L if __name__ == '__main__': docs = read_file_content() print(docs)
文件的迭代读取:
open返回的文件流对象是可迭代对象;
5、文本文件的写操作:
写文件模式有:
'w'
'x'
'a'
文件操作模式:
'r' 以只读方式打开(默认) 'w' 以只写方式打开,删除原有文件内容(如果文件不存在,则创建该文件并以只写方式打开) 'x' 创建一个新文件, 并以写模式打开这个文件,如果文件存在则会产生"FileExistsError"错误 'a' 以只写文件打开一个文件,如果有原文件则追加到文件末尾 'b' 用二进制模式打开 't' 文本文件模式打开 (默认) '+' 为更新内容打开一个磁盘文件 (可读可写)</td> 缺省模式是 'rt' 'w+b' 可以实现二进制随机读写,当打开文件时,文件内容将被清零 'r+b' 以二进制读和更新模式打开文件,打开文件时不会清空文件内容 'r+' 以文本模式读和更新模式打开文件,打开文件时不会清空文件内容
6、二进制文件操作:
默认的文件中存储的都是以字节为单位的数据,通常有人为规则的格式,需要以字节为单位进行读写;
linux下#man ascii
ubuntu#xxd baidu.gif | head #ubuntu以十六进制方式查看图片(baidu.gif)
F.read() 的返回类型:
1.对于文本模式(’t')打开的文件,返回字符串str;
2.对于二进制模块('b')打开的文件,返回字节器bytes;
F.write(x)
1.对于文本模式,x必须为字符串;
2.对于二进制模块,x必须为字节串;
以十六进制方式查看 文件内容的命令:
# xxd 文件名 #以十六进制方式查看文件
#file_write_binary.py #示意以二进制方式写文件到’data.bin‘ try: f = open('data.bin', 'wb') print('open 成功') #写入数据 b = b'\xe4\xb8\xad' f.write(b) f.write(b'\x00\x00') f.close() except OSError: print('file open fail ') str1 = '15683359115' b = str1.encode('utf-8')
F.seek()方法:
F.seek(偏移量,相对位置)
偏移量:
大于0的数代表向文件尾方向移动;
小于0的数代表向文件头方向移动;
相对位置:
0代表从文件头开始偏移;
1代表从当前位置开始偏移;
2代表从文件尾开始偏移;
作用:
改变当前文件的读写位置;
注:seek 通常对 二进制模式打开的文件进行操作;
F.tell()方法:
作用:
返回当前文件读写位置;
小结:
文件操作的两种模式:
'b' 二进制模式
't' 文本模式
==检索指定目录,下所有后辍为Py的文件== import os import os.path #检索指定路径下,所有后辍为py的文件 ls = [] def getAppointPathFile(path, ls): filelist = os.listdir(path) #列出目录下所有文件包括子目录 try: for tmp in filelist: pathTmp = os.path.join(path, tmp) #将路径与filelist组合 if True == os.path.isdir(pathTmp): getAppointPathFile(pathTmp, ls) #对子目录使用递归继续深入检索 elif pathTmp[pathTmp.rfind('.') + 1:].upper() == 'PY': #取文件后辍,变将后辍大写 ls.append(pathTmp) except PermissionError: pass def main(): while True: path = input('请输入路径:').strip() if os.path.isdir(path) == True: break getAppointPathFile(path, ls) for file in ls: print(file) print(len(ls)) main()
回顾:
1.迭代器:it = iter(可迭代对象)
value = next(it) #从迭代器中获取值,当没有数据时触发StopIteration通知;
2.生成器:创建可迭代对象,提供动态生成数据对象;
生成器有两种:生成器函数和生成器表达式
生成器函数:
含有yield语句的函数是生成器函数
yield 表达式
yield作用: 是为next(it) 函数提供数据,生成器函数的执行流程和函数不同。
生成器表达式:(x ** 2 for x in range(10)) 注意与列表推导式区分开
3.迭代相关的函数:(也称生成器函数)
zip(iter1, iter2, iter3, .....) 返回一个zip对象,此对象用于生成一个元组,此元组中的元素分别由iter1,iter2可迭代对象中的元组构成(元组个数由最小的可迭代对象决定);
enumerate(iterable, start=0) 生成带索引的枚举对象,返回的迭代类型为索引-值对(index-value)对,默认索引从零开始,也可用start指定; 序号;
4.容器类 :字节串 bytes 字节数组 bytearray
5.str.encode(编码字符串) 转为bytes
bytes.decode(编码字符器) 转为str
1.文件 file 存储以字节为单位的数据;
文件的打开模式:二进制模式'b' 文本模式't' 默认
文件的操作模式:读 'r' 写 'w', 'a'追加, 'x'文件存在报错,没有报错
F.close()
F.read(n=-1) /F.feadline() /F.readlines()
F.write(x) / F.writelines(列表)
F.seek(偏移量offset,起始位置whence)
F.tell() 获取当前读取位置
文件流对象是可迭代对象
压缩算法:zip unzip huffman
2.汉字编码:
GB18030(GBK(GB2312))
UNICODE32(UNICODE16) ---->UTF-8 (8-bit Unicode Tranfromation Fortat)
3.编码字符串
'gb18030' / 'gbk' / 'gb2312'
'utf-8'
'ascii'
4.编码注释:
#-*- coding: utf-8 -*- 告诉解释器编码是什么utf-8