zoukankan      html  css  js  c++  java
  • 第四节

    迭代器

    可以直接作用于for循环的数据类型有以下几种:

    一类是集合数据类型,如listtupledictsetstr等;

    一类是generator,包括生成器和带yield的generator function。

    这些可以直接作用于for循环的对象统称为可迭代对象:Iterable

    可以使用isinstance()判断一个对象是否是Iterable对象:

    >>> from collections import Iterable
    >>> isinstance([], Iterable)
    True
    >>> isinstance({}, Iterable)
    True
    >>> isinstance('abc', Iterable)
    True
    >>> isinstance((x for x in range(10)), Iterable)
    True
    >>> isinstance(100, Iterable)
    False
    

    而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。

    可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator

    可以使用isinstance()判断一个对象是否是Iterator对象:

    >>> from collections import Iterator
    >>> isinstance((x for x in range(10)), Iterator)
    True
    >>> isinstance([], Iterator)
    False
    >>> isinstance({}, Iterator)
    False
    >>> isinstance('abc', Iterator)
    False
    

    生成器都是Iterator对象,但listdictstr虽然是Iterable,却不是Iterator

    listdictstrIterable变成Iterator可以使用iter()函数:

    >>> isinstance(iter([]), Iterator)
    True
    >>> isinstance(iter('abc'), Iterator)
    True

      Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

    Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。

    names = iter(('tom','marrry','jack'))
    print(names)
    print(names.__next__())
    print(names.__next__())
    print(names.__next__())

    1.生成器

    def crash_money(amount):
    while amount > 0:
    amount -= 1
    yield 100  #yield会终止方法的执行,直到下一次再次调用迭代器,迭代器会从终止的地方继续执行迭代器,以此循环,直到迭代器执行完毕。
    print("取出100块钱")

    atm = crash_money(500)
    print(atm)
    print(atm.__next__())
    print(atm.__next__())
    print("hahahahahahah")
    print(atm.__next__())

    显示结果:
    <generator object crash_money at 0x0000007502A2B150>
    100
    取出100块钱
    100
    hahahahahahah
    取出100块钱
    100
    #迭代器可以保存函数的执行状态,即使是一个循环函数,终止状态后可以处理其他事情,处理完后可以继续执行迭代器方法

    2.使用yield实现单线程中的异步并发
    import time
    def consumer(name):
    print("%s准备吃包子" % name)
    while True:
    baozi = yield
    print("包子[%s]来了,被[%s]吃了!" % (baozi,name))

    def producer(name):
    c1 = consumer("A")
    c2 = consumer("B")
    c1.__next__()
    c2.__next__()
    print("老子要开始吃包子啦!")
    for i in range(10):
    time.sleep(1)
    print("做了两个包子")
    c1.send(i)
    c2.send(i)

    producer("cjfpjt")
    3.装饰器的实现
    例:(非装饰器)
    def login(func):
    print("passed user verfication...")
    return func
    def tv(name):
    print("Welcome [%s] to tv page!" % name)
    
    
    tv = login(tv)  #login函数实现了对tv函数的重构,起到了装饰器的作用
    tv("cjfpjt")
    例:(含装饰器)
    def login(func):
    def inner(arg):
    print("passed user verfication...")
    func(arg)
    return inner
    @login  #装饰器将tv()方法的内存地址做了一个包装
    def tv(name):
    print("Welcome [%s] to tv page!" % name)


    tv("cjfpjt")
    显示结果:
    passed user verfication...
    Welcome [cjfpjt] to tv page!

    4.实现带参数的复杂装饰器
    def before_fuc(request,kargs):
    print(request)

    def after_fuc(request,kargs):
    print(kargs)

    def filter(before_fuc,after_fuc):
    def warrp(main_fuc):
    def outer(request,kargs):
    before_fuc(request,kargs)
    main_fuc(request,kargs)
    after_fuc(request,kargs)
    return outer
    return warrp

    @filter(before_fuc,after_fuc)
    def tv(request,respond):
    print("index")

    tv("pjt","ttyy")

    递归原理及其实现

    整个递归结束后,递归结果会一层一层的逐级返回,所以递归会浪费资源。
    def calc(n):
    print(n)
    if n > 1:
    res = calc(n/2)
    print("res:",res)
    print("N:",n)
    return n

    calc(10)

    显示结果:
    10
    5.0
    2.5
    1.25
    0.625
    N: 0.625
    res: 0.625
    N: 1.25
    res: 1.25
    N: 2.5
    res: 2.5
    N: 5.0
    res: 5.0
    N: 10
    递归实现斐波那契数列
    def func(arg1,arg2,stop):
    if arg1 == 0:
    print(arg1,arg2)
    arg3 = arg1 + arg2
    print(arg3)
    if arg3 < 30:
    func(arg2,arg3,stop)

    func(0,1,30)
    显示结果:
    0 1
    1
    2
    3
    5
    8
    13
    21
    34

    算法基础之二分查找
    def binary_search(data_source,find_n):
    if len(data_source) >= 1:
    mid = int(len(data_source)/2)
    if data_source[mid] > find_n:
    print("The number %s you want in left" % find_n)
    print(data_source[:mid])
    binary_search(data_source[:mid], find_n)
    elif data_source[mid] < find_n:
    print("The number %s you want in right" % find_n)
    print(data_source[mid:])
    binary_search(data_source[mid:], find_n)
    else:
    print(data_source[mid])
    print("find data %s" % find_n)
    else:
    print("Not found........")

    if __name__ == '__main__':
    data = list(range(1,600,3))
    binary_search(data,322)
    显示结果:
    The number 322 you want in right
    [301, 304, 307, 310, 313, 316, 319, 322, 325, 328, 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364, 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400, 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436, 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472, 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508, 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544, 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580, 583, 586, 589, 592, 595, 598]
    The number 322 you want in left
    [301, 304, 307, 310, 313, 316, 319, 322, 325, 328, 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364, 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400, 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436, 439, 442, 445, 448]
    The number 322 you want in left
    [301, 304, 307, 310, 313, 316, 319, 322, 325, 328, 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364, 367, 370, 373]
    The number 322 you want in left
    [301, 304, 307, 310, 313, 316, 319, 322, 325, 328, 331, 334]
    The number 322 you want in right
    [319, 322, 325, 328, 331, 334]
    The number 322 you want in left
    [319, 322, 325]
    322
    find data 322

    算法基础之2维数组90度旋转
    data = [[i for i in range(4)] for j in range(4)]
    print(data)
    for aa in data: print(aa)
    '''
    [0, 1, 2, 3]
    [0, 1, 2, 3]
    [0, 1, 2, 3]
    [0, 1, 2, 3]

    [0, 0, 0, 0]
    [1, 1, 1, 1]
    [2, 2, 2, 2]
    [3, 3, 3, 3]
    '''

    for i in range(len(data)):
    for j in range(i,len(data)):
    tmp = data[i][j]
    data[i][j] = data[j][i]
    data[j][i] = tmp
    print("----------------------")
    for b in data: print(b)

    # print("----------------------")
    # for b in data:print(b)


    正则表达式

    import re

    m = re.match("abc","abcdefg")
    print(m.group())
    #从0开始匹配0-10个数字
    m = re.match("[0-9]{0,10}","234567tdfsgdf6sg")
    print(m.group())
    #匹配10个数字
    m = re.match("[0-9]{10}","234567tdfsgdf6sg")
    if m:
    print("-------------"+m)
    #从所有变量匹配1-10个数字
    m = re.findall("[0-9]{1,10}","28956tdfdf6sg")
    if m:
    print(m)
    #从所有变量匹配1-10个字母
    m = re.findall("[a-zA-Z]{1,10}","28956tdfdf6sg")
    if m:
    print(m)
    #所有变量从0开始匹配所有变量
    m = re.findall(".*","28956tdfdf6sg")
    if m:
    print(m)
    #所有变量,匹配所有,每个变量为一个字符串
    m = re.findall(".","28956tdfdf6sg")
    if m:
    print(m)
    #所有变量从1开始匹配所有
    m = re.findall(".+","28956tdfdf6sg")
    if m:
    print(m)
    #查找所有字母
    m = re.findall("[a-zA-Z]+","28956td_fd+f6@s%g")
    if m:
    print(m)
    #
    m = re.search("d+","dfg8956tdfdsf6567")
    if m:
    print(m.group())
    #替换所有数字
    m = re.sub("d+","|","dfg89fh56td_fd+f6yh567@s%g")
    if m:
    print(m)
    #只替换前两个
    m = re.sub("d+","|","dfg89fh56td_fd+f6yh567@s%g",count=2)
    if m:
    print(m)

     数据序列化

    1.json序列化
    import json

    info = {
    "name":"panjiatao",
    "age":25
    }

    f = open("test.txt","w")
    f.write(json.dumps(info))
    f.close()


    json反序列化
    import json

    f = open("test.txt","r")
    data = json.loads(f.read())
    f.close()
    print(data)

    运行结果:
    {'name': 'panjiatao', 'age': 25}

    #存储的文件直接以字符串形式保存,取出时候数据恢复,文件内容可直接查看,但是存储的数据只能为字符串格式

    2.pickle序列化
    import pickle

    def sayhi(name):
    print("hello",name)

    info = {
    "name":"panjiatao",
    "age":25,
    "func":sayhi
    }

    f = open("test2.txt","wb")
    f.write(pickle.dumps(info))
    f.close()

    pickle反序列化
    import pickle

    def sayhi(name):
    print("hello",name)

    f = open("test2.txt","rb")
    data = pickle.loads(f.read())
    f.close()
    print(data["func"]("panjiatao"))
    print(data)

    运行结果:
    hello panjiatao
    None
    {'name': 'panjiatao', 'age': 25, 'func': <function sayhi at 0x000000668A7B3E18>}
    #pickle可以对整个数据进行二进制存储,例如对一个方法进行存储,这是json做不到的

    在进行数据的dumps与loads时,load只会把最近的dump数据取出,所以在文件转储时,一个dump只对应一个load,如果需要进行多个转储,可以将数据存储在不同文件。
     
     





     

  • 相关阅读:
    live-server
    vue-插槽
    100%的背影
    Luogu P3243 菜肴制作
    CF512E Fox And Polygon
    BZOJ2523/LOJ2646 聪明的学生
    Luogu P3959 宝藏
    Luogu P2280 激光炸弹
    ACAG 0x02-8 非递归实现组合型枚举
    ACAG 0x02-4 费解的开关
  • 原文地址:https://www.cnblogs.com/ttyypjt/p/6940475.html
Copyright © 2011-2022 走看看