Python 基础7 迭代器 、生成器、序列、文件

迭代器 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

猜你喜欢

转载自www.cnblogs.com/pineliao/p/12101980.html
今日推荐