zoukankan      html  css  js  c++  java
  • python1.day15

    day14回顾
       异常
         错误
         异常
         作用:
           用作信号通知
         语句:
           try-except语句
             捕获异常,将程序由异常流程转为正常流程
           try-finally语句
             保证(正常/异常)流程时,有些语句一定能执行
           raise 语句
             触发异常通知,让程序进入异常流程
           assert 语句
             根据条件触发AssertionError类型的错误
         异常类型:
            ValueError, ImportError, ZeroDivisionError,
            StopIteration, AssertionError, ....
            BaseExcetion(基类)

      迭代器
         什么是迭代器?
           函数:
             iter(可迭代对象)   获取并返回迭代器
             next(迭代器)    从迭代器中取数据,如果没有数据时会收到
                            StopIteration异常通知

        for in 语句的实质是while语句+迭代器+try语句的组合



    day15笔记:
    生成器 Genertor (python2.5及之后)
       什么是生成器
         生成器是能够动态提供数据的可迭代对象
         生成器是在程序运行时生成数据,与容器类不同,它通常不会在内
           存在中保存大量的数据,而是现用现生成

      生成器有两种:
         生成器函数
         生成器表达式

      
    生成器函数的定义
       含有yield 的语句的函数是生成器函数。此函数被调用将返回一
       个生成器对象
       yield翻译为(产生或生成)

    yield语句
       语法:
          yield 表达式
       说明:
         yield 用于def函数中,目的是将此函数作为生成器函数使用
         yield 用来生成数据,供迭代器的next(it) 函数使用
      示例见:
         yield.py

     

      1 # yield.py
      2 
      3 # 此示例示意生成器函数的定义和使用
      4 def myyield():
      5     print("即将生成2")
      6     yield 2  # 生成2
      7     print("即将生成3")
      8     yield 3  # 生成3
      9     print("即将生成5")
     10     yield 5
     11     print("即将生成7")
     12     yield 7
     13     print("myyield函数运行结束!")
     14 
     15 
     16 
     17 g = myyield()  # 生成器函数调用将返回生成器对象,g绑写一个生成器
     18 # print(g)
     19 it = iter(g)  # 让生成器提供迭代器
     20 print(next(it))  # 2
     21 
     22 print(next(it))  # 3
     23 
     24 print(next(it))  # 5
     25 
     26 print(next(it))  # 7
     27 
     28 print(next(it))  # StopIteration异常
     29 print("程序正常结束")
     30 
     31 
     32 
     33 
    yield.py

      1 # yield.py
      2 
      3 # 此示例示意生成器函数的定义和使用
      4 def myyield():
      5     print("即将生成2")
      6     yield 2  # 生成2
      7     print("即将生成3")
      8     yield 3  # 生成3
      9     print("即将生成5")
     10     yield 5
     11     print("即将生成7")
     12     yield 7
     13     print("myyield函数运行结束!")
     14 
     15 for x in myyield():
     16     print(x)
     17 
     18 
     19 print("程序正常结束")
     20 
     21 
     22 
     23 
     24 
     25 
     26 
    yield2.py

    生成器函数说明:
       1. 生成器函数的调用将返回一个生成器对象,生成器对象是一个可迭
          代对象
       2. 在生成器函数调用return会触发一个StopIteration异常(即
          生成数据结束)
       生成器函数示例见:
         myinteger.py

      1 # myinteger.py
      2 
      3 # 此示例示意自己写一个生成器函数,可以生成从0开始的一系列
      4 # 整数,到n结束(不包含n)
      5 def myinteger(n):
      6     i = 0
      7     while i < n:
      8         yield i
      9         i += 1
     10 
     11 
     12 for x in myinteger(3):
     13     print(x)
     14 
     15 
     16 
    myinteger.py

    练习:
       1. 写一个生成器函数myeven(begin, end), 用来生成从begin开始
          到end结束的所有偶数(不包含end)
         如:
             def myeven(begin, end):
                 ... 此处自己实现

            for x in myeven(1, 10):
                 print(x)  # 打印 2, 4, 6, 8
             L = [x**2 for x in myeven(4, 9)]
             print(L)  # [16, 36, 64]

      1 # 练习:
      2 #   1. 写一个生成器函数myeven(begin, end), 用来生成从begin开始
      3 #      到end结束的所有偶数(不包含end)
      4 #     如:
      5 #         def myeven(begin, end):
      6 #             ... 此处自己实现
      7 
      8 #         for x in myeven(1, 10):
      9 #             print(x)  # 打印 2, 4, 6, 8
     10 #         L = [x**2 for x in myeven(4, 9)]
     11 #         print(L)  # [16, 36, 64]
     12 
     13 
     14 def myeven(begin, end):
     15     i = begin
     16     while i < end:
     17         if i % 2 == 0:  # 是偶数
     18             yield i
     19         i += 1
     20 
     21 for x in myeven(1, 10):
     22     print(x)  # 打印 2, 4, 6, 8
     23 
     24 L = [x**2 for x in myeven(4, 9)]
     25 print(L)  # [16, 36, 64]
     26 
    myeven.py

    生成器表达式:
       语法:
         (表达式 for 变量 in 可迭代对象 [if 真值表达式])
       说明:
         if 子句可以省略
       作用:
         用推导式形式创建一个新的生成器
       示例:
         gen = (x**2 for x in range(1, 5))
         it = iter(gen)  # 拿到迭代器
         print(next(it))  # 1
         print(next(it))  # 4
         print(next(it))  # 9
         print(next(it))  # 16
         print(next(it))  # StopIteration

    说明:
       生成器通常是一次性的,当数据获取完毕后将不能再提供数据

    练习:
       已知有列表:
         L = [2, 3, 5, 7]
       1. 写一个生成器函数,让此函数能够动态提供数据,数据为原列
          表的数字的平方加1
       2. 写一个生成器表达式,让此表达式能够动态提供数据,数据为原
          列表的数字的平方加1
       3. 创建一个列表,此列表内的数据为原列表L的数字的平方加1

      1 # 练习:
      2 #   已知有列表:
      3 #     L = [2, 3, 5, 7]
      4 #   1. 写一个生成器函数,让此函数能够动态提供数据,数据为原列
      5 #      表的数字的平方加1
      6 #   2. 写一个生成器表达式,让此表达式能够动态提供数据,数据为原
      7 #      列表的数字的平方加1
      8 #   3. 创建一个列表,此列表内的数据为原列表L的数字的平方加1
      9 
     10 
     11 
     12 L = [2, 3, 5, 7]
     13 #   1. 写一个生成器函数,让此函数能够动态提供数据,数据为原列
     14 #      表的数字的平方加1
     15 def fun1(lst):
     16     for x in lst:
     17         yield x ** 2 + 1
     18 
     19 # for x in fun1(L):
     20 #     print(x)
     21 
     22 #   2. 写一个生成器表达式,让此表达式能够动态提供数据,数据为原
     23 #      列表的数字的平方加1
     24 
     25 for x in (a ** 2 + 1 for a in L):
     26     print(x)
     27 
     28 #   3. 创建一个列表,此列表内的数据为原列表L的数字的平方加1
     29 L = [a ** 2 + 1 for a in L]
     30 print(L)
     31 
     32 

    练习:
       试写一个生成器函数 myfilter,要求此函数与系统内建的filter
       函数功能完全一致
         如:
             def myfilter(fn, iterable):
                 ....
            
             for y in myfilter(lambda x: x%2==0, range(10)):
                 print(y)

      1 # 练习:
      2 #   试写一个生成器函数 myfilter,要求此函数与系统内建的filter
      3 #   函数功能完全一致
      4 #     如:
      5 #         def myfilter(fn, iterable):
      6 #             ....
      7 
      8 #         for y in myfilter(lambda x: x%2==0, range(10)):
      9 #             print(y)
     10 
     11 
     12 
     13 
     14 def myfilter(fn, iterable):
     15     for x in iterable:
     16         if fn(x):
     17             yield x
     18 
     19 for y in myfilter(lambda x: x%2==0, range(10)):
     20     print(y)

       2. 看下列语句块的输出结果是什么?为什么?
         第一个程序:
             L = [2, 3, 5, 7]
             A = [x*10 for x in L]
             it = iter(A)
             print(next(it))  # 20
             L[1] = 33
             print(next(it))  # 30
         第二个程序:
             L = [2, 3, 5, 7]
             A = (x*10 for x in L)
             it = iter(A)
             print(next(it))  # 20
             L[1] = 33
             print(next(it))  # 330


    迭代工具函数
       zip 函数
      enumerate 函数

    zip函数
       zip(itere1[,iter2, ....])  返回一个zip生成器对象,此对象
                  用于生成一个元组,此元组的数据分别来自于参数中的
                  每个可迭代对象,生成元组的个数由最小的可迭代对象大
                  小决定
       示例:
         numbers = [10086, 10000, 10010, 95588]
         names = ['中国移动', '中国电信', '中国联通']
         for t in zip(numbers, names):
             print("t=", t)
         for n, na in zip(numbers, names):
             print(na, '的客服电话是:', n)

        d = dict(zip(numbers, names))  # 创建字典

        for t in zip(numbers, names, range(1, 100000)):
             print(t)


    zip 函数的实现原理示例见:
         myzip.py


    enumerate 函数
       格式:
         enumerate(iterable, start=0)

       作用:
         生成一个枚举对象,此枚举对象生成的数据将原可迭代对象的数据与
         索引值形成元组(index, value) 形式返回
       示例:
         L = [3, 5, 8, 10]
         for i, v in enumerate(L):
             print('索引为', i, '的元素值为', v)

    练习:
       试用自己的方法实现myenumerate, 功能与enumerate完全相同
         def myenumerate(iterable, start=0):
             ...  # 此处自己实现

        L = [3, 5, 8, 10]
         for i, v in myenumerate(L):
             print('索引为', i, '的元素值为', v)

      1 # 练习:
      2 #   试用自己的方法实现myenumerate, 功能与enumerate完全相同
      3 #     def myenumerate(iterable, start=0):
      4 #         ...  # 此处自己实现
      5 
      6 #     L = [3, 5, 8, 10]
      7 #     for i, v in myenumerate(L):
      8 #         print('索引为', i, '的元素值为', v)
      9 
     10 
     11 # 方法1 用while语句实现
     12 # def myenumerate(iterable, start=0):
     13 #     it = iter(iterable)  # 拿到迭代器
     14 #     while True:
     15 #         try:
     16 #             v = next(it)  # 拿到一个值
     17 #             yield (start, v)
     18 #             start += 1
     19 #         except StopIteration:
     20 #             return
     21 
     22 # 方法2 用for语句实现
     23 def myenumerate(iterable, start=0):
     24     for v in iterable:
     25         yield (start, v)
     26         start += 1
     27 
     28 L = [3, 5, 8, 10]
     29 for i, v in myenumerate(L):
     30     print('索引为', i, '的元素值为', v)
     31 
     32 
     33 
     34 
     35 
     36 
     37 

    字节串和字节数组

    字节串 bytes(也叫字节序列)
       作用:
         存储以字节为单位的数据
         字节串是不可变的字节序列
    字节:
       字节是0~255之间的整数。用来表一个字节(8个位)的取值
       字节是数据存储的最小单位


    创建空字节串的字面值:
        B = b''   # B绑定空字节串
        B = b""
        B = b''''''
        B = b""""""

    创建非空字节串的字面值:
       B = b'ABCD'
       B = b"ABCD"
       B = b'x41x42x43x44'

    字节串的构造函数 bytes
       bytes()   生成一个空的字节串,等同于b''
       bytes(整数可迭代对象)  用可迭代对象初始化一个字节串
       bytes(整数n)    生成n个值为0的字节串
       bytes(字符串,encoding='utf-8')   用字符串转换编码生成一个
             字节串

    示例:
       B = bytes()                    # B=b''
       B = bytes(range(65, 69))       # B = b'ABCD'
       B = bytes(10)                  # B=b'x00x00....'
       B = bytes("hello", 'utf-8')    # B=b'hello'


    bytes 的运算:
       +  +=  *  *=
       < <= > >= == !=
       in / not in
       索引和切片

    示例:
       b = b'abc123ABC'
       b'A' in b  # True
       65 in b   # True
       print(b[0])  # 97

    函数:
       len(x), max(x), min(x), sum(x), any(x), all(x)

    bytes 与 str的区别:
       bytes 存储字节(0~255)
       str存储unicode字符  (0~0x10FFFF)

    bytes与str转换
             编码(encode)
       str   -----------> bytes
           b = s.encode(encoding='utf-8')

         解码(decode)
       bytes  -----------> str     
           s = b.decode(encoding='utf-8')

      示例:
         s = "ABC中文"
         b = s.encode('utf-8')  # b = b'ABCxe4xb8xadxe6x96x87'

        s2 = b.decode('utf-8')  # s2 = 'ABC中文'


    字节数组 bytearray
       可变的字节序列

    字节数组的构造函数 bytearray
        (同字节串)
       bytearray()   生成一个空的字节数组,等同于bytearray(b'')
       bytearray(整数可迭代对象)  用可迭代对象初始化一个字节数组
       bytearray(整数n)    生成n个值为0的字节数组
       bytearray(字符串,encoding='utf-8')   用字符串转换编码生成一个
             字节数组


    运算:
       +  +=  *  *=
       < <= > >= == !=
       in / not in
       索引Index / 切片 slice
       (注: 字节数组的索引和切片可以赋值操作,规则同列表的索引和切片
       赋值规则相同)

    bytearray 的方法:
       参见文档:
         python_base_docs_html/bytearray.html


    文件 File
       什么是文件
         文件是用于数据存储的单位
         文件通常用来长期存储数据
         文件中的数据是以字节为单位进行顺序存储的
     
       文件操作的流程
         1. 打开文件
         2. 读写文件
         3. 关闭文件


      文件的打开和关闭:
         文件需要在使用时先打开文件才能读写
         在不需要读写文件时,应及时关闭文件以释放系统资源
         任何操作系统,一个应用程序同时打开文件的数量有最大数限制

      文件的打开函数:
         open(file, mode='rt')  用于打开一个文件,返回此文件对象
                          如果打开失败,则会触发OSError类型的错误
            
      文件的关闭方法:
        F.close()  关闭文件,释放系统资源
       文本文件的读取数据方法:
         F.read([n])
         F.readline()
         F.readlines()
         (文档参见: python_base_docs_html/文件.html)

      1 mode 模式字符的含义
      2 字符	含义
      3 'r'	以只读方式打开(默认)
      4 'w'	以只写方式打开,删除原有文件内容(如果文件不存在,则创建该文件并以只写方式打开)
      5 'x'	创建一个新文件, 并以写模式打开这个文件,如果文件存在则会产生"FileExistsError"错误
      6 'a'	以只写文件打开一个文件,如果有原文件则追加到文件末尾
      7 'b'	用二进制模式打开
      8 't'	文本文件模式打开 (默认)
      9 '+'	为更新内容打开一个磁盘文件 (可读可写)
     10 缺省模式是 'rt'
     11 'w+b' 可以实现二进制随机读写,当打开文件时,文件内容将被清零
     12 'r+b' 以二进制读和更新模式打开文件,打开文件时不会清空文件内容
     13 'r+' 以文本模式读和更新模式打开文件,打开文件时不会清空文件内容
     14 python 文件常用方法:
     15 方法	说明
     16 F.close()	关闭文件(关闭后文件不能再读写会发生ValueError错误)
     17 F.readline()	读取一行数据, 如果到达文件尾则返回空行
     18 F.readlines(max_chars=-1)	返回每行字符串的列表,max_chars为最大字符(或字节)数
     19 F.writelines(lines)	每行字符串的列表
     20 F.flush()	把写入文件对象的缓存内容写入到磁盘
     21 F.read(size = -1)	从一个文件流中最多读取size个字符
     22 F.write(text)	写一个字符串到文件流中,返回写入的字符数
     23 二进制文件操作方法
     24 F.tell()	返回当前文件流的绝对位置
     25 F.seek(offset, whence=0)	改变数据流的位置,返回新的绝对位置
     26 F.readable()	判断这个文件是否可读,可读返回True,否则返回False
     27 F.writable()	判断这个文件是否可写,可写返回True,否则返回False
     28 F.seekable()	返回这个文件对象是否支持随机定位
     29 F.truncate(pos = None)	剪掉 自pos位置之后的数据,返回新的文件长度(字节为单位)


       示例见:
         file_open.py

      1 # file_open.py
      2 
      3 # 此示例示意打开一个文件, 同时对文件的内容进行读取操作
      4 
      5 # 1. 打开文件
      6 # f = open("myzip.py")
      7 f = open("myfile.txt")
      8 print("文件打开成功")
      9 
     10 # 2.读取文件
     11 
     12 # 3. 关闭文件
     13 f.close()
     14 print("文件关闭成功")
     15 
     16 
    file_open.py

    练习:
       1. 写一个生成器函数myxrange(start, stop, step) 来生成一
         系列整数,
           要求:
             myxrange的功能与range功能完全相同
             不允许调用range函数和列表
            用自己写的myxrange结合生成器表达式求 1~10内的奇数的平方和
           print(sum((x for x in myxrange(1, 10) if x%2)))
        
       2. 自己写一个文件(si.txt)内容如下:
          写入内容如下:
            xiaozhang,20,100
            ziaoli,18,98
            ziaowang,19,80
         为学生信息管理系统添加一个功能
           | 9) 从文件中读取学生数据(si.txt) |
         读取学生信息并加载到内存中

      1 # file : main.py
      2 
      3 from menu import show_menu
      4 from student_info import *
      5 
      6 def main():
      7     infos = []  # 此列表用于保存学生数据
      8     while True:
      9         show_menu()
     10         s = input("请选择: ")
     11         if s == '1':
     12             infos += input_student()
     13         elif s == '2':
     14             output_student(infos)
     15         elif s == '3':
     16             delete_student(infos)
     17         elif s == '4':
     18             modify_student_score(infos)
     19         elif s == '5':
     20             output_by_score_desc(infos)
     21         elif s == '6':
     22             output_by_score_asc(infos)
     23         elif s == '7':
     24             output_by_age_desc(infos)
     25         elif s == '8':
     26             output_by_age_asc(infos)
     27         elif s == '9':
     28             infos = read_from_file()
     29         elif s == '10':
     30             save_to_file(infos)  # 保存
     31         elif s == 'q':
     32             break
     33 
     34 main()
     35 
    main
      1 # file : menu.py
      2 
      3 
      4 def show_menu():
      5     '''显示菜单'''
      6     print("+---------------------------------+")
      7     print("| 1) 添加学生信息                 |")
      8     print("| 2) 显示学生信息                 |")
      9     print("| 3) 删除学生信息                 |")
     10     print("| 4) 修改学生成绩                 |")
     11     print("| 5) 按学生成绩高-低显示学生信息  |")
     12     print("| 6) 按学生成绩低-高显示学生信息  |")
     13     print("| 7) 按学生年龄高-低显示学生信息  |")
     14     print("| 8) 按学生年龄低-高显示学生信息  |")
     15     print("| 9) 从文件中读取学生数据(si.txt) |")
     16     print("| 10) 保存信息到文件(si.txt)      |")
     17     print("| q) 退出                         |")
     18     print("+---------------------------------+")
     19 
     20 
    menu.py


      1 # file: student.py
      2 
      3 def input_student():
      4     L = []  # 创建一个列表,准备存放学生数据的字典
      5     while True:
      6         n = input("请输入姓名: ")
      7         if not n:  # 如果用户输入空字符串就结束输入
      8             break
      9         try:
     10             a = int(input("请输入年龄: "))
     11             s = int(input("请输入成绩: "))
     12         except ValueError:
     13             print("您的输入有错,请重新输入!!!")
     14             continue
     15         d = {}  # 一定要每次都创建一个新的字典
     16         d['name'] = n
     17         d['age'] = a
     18         d['score'] = s
     19         L.append(d)   # 把d加入列表中L
     20     return L
     21 
     22 def output_student(L):
     23     print("+---------------+----------+----------+")
     24     print("|     姓名      |   年龄   |   成绩   |")
     25     print("+---------------+----------+----------+")
     26     for d in L:
     27         name = d['name']
     28         age = str(d['age'])  # 转为字符串
     29         score = str(d['score'])  # 转为字符串
     30         print("|%s|%s|%s|" % (name.center(15),
     31                             age.center(10),
     32                             score.center(10)))
     33     print("+---------------+----------+----------+")
     34 
     35 def delete_student(L):
     36     name = input("请输入要删除学生的姓名: ")
     37     i = 0  # i 代表列表的索引
     38     while i < len(L):
     39         d = L[i]  # d绑定字典
     40         if d['name'] == name:
     41             del L[i]
     42             print("删除", name, "成功!")
     43             break
     44         i += 1
     45     else:
     46         print("删除失败!")
     47 
     48 def modify_student_score(L):
     49     pass
     50 
     51 
     52 def output_by_score_desc(L):
     53     def get_score(d):
     54         return d['score']
     55     L2 = sorted(L, key=get_score, reverse=True)
     56     output_student(L2)
     57 
     58 def output_by_score_asc(L):
     59     L2 = sorted(L, key=lambda d:d['score'])
     60     output_student(L2)
     61 
     62 def output_by_age_desc(L):
     63     L2 = sorted(L, key=lambda d:d['age'], reverse=True)
     64     output_student(L2)
     65 
     66 def output_by_age_asc(L):
     67     L2 = sorted(L, key=lambda d:d['age'])
     68     output_student(L2)
     69 
     70 
     71 def read_from_file():
     72     L = []  # 创建一个准备存放字典的列表
     73     try:
     74         # 1. 打开文件
     75         # f = open("./si.txt")
     76         # f = open("si.txt")
     77         f = open("/home/tarena/aid1812/pbase/day16/student_project/si.txt")
     78         # 2. 读取信息
     79         try:
     80             while True:
     81                 line = f.readline()  # line='xiaozhang,20,100
    '
     82                 if not line:  # 到达文件尾
     83                     break
     84                 s = line.strip()  # 去掉左右两端的空白字符'xiaozhang,20,100'
     85                 lst = s.split(',')  # ['xiaozhang', '20', '100']
     86                 n = lst[0]
     87                 a = int(lst[1])
     88                 scr = int(lst[2])
     89                 d = dict(name=n, age=a, score=scr)
     90                 L.append(d)
     91         finally:
     92             # 3. 关闭文件
     93             f.close()
     94             print("读取数据成功")
     95     except OSError:
     96         print("读取数据失败")
     97     except ValueError:
     98         print("数据类型错误!")
     99     return L
    100 
    101 def save_to_file(L):
    102     try:
    103         f = open("si.txt", 'w')
    104         # 循环写入每个学生的信息
    105         for d in L:
    106             # 每次写入一个学生的信息
    107             f.write(d['name'])  # 姓名
    108             f.write(',')
    109             f.write(str(d['age']))  # 年龄
    110             f.write(',')
    111             f.write(str(d['score']))  # 成绩
    112             f.write('
    ')  # 换行
    113         f.close()
    114         print("保存成功")
    115     except OSError:
    116         print("保存失败!")
    117 
    student.py
  • 相关阅读:
    codechef Dynamic GCD [树链剖分 gcd]
    bzoj 4546: codechef XRQRS [可持久化Trie]
    bzoj 4835: 遗忘之树 [树形DP]
    bzoj 4033: [HAOI2015]树上染色 [树形DP]
    bzoj 4591: [Shoi2015]超能粒子炮·改 [lucas定理]
    3167: [Heoi2013]Sao [树形DP]
    bzoj 3812: 主旋律 [容斥原理 状压DP]
    有标号的二分图计数 [生成函数 多项式]
    有标号DAG计数 [容斥原理 子集反演 组合数学 fft]
    BZOJ 3028: 食物 [生成函数 隔板法 | 广义二项式定理]
  • 原文地址:https://www.cnblogs.com/shengjia/p/10323267.html
Copyright © 2011-2022 走看看