• Python3(十二) Pythonic与Python杂记


    一.用字典映射代替switch case语句

    if/else可以代替switch但是非常不合适。

    用字典代替switch:

    day = 5
    
    switcher = {
    
        0:'Sunday',
    
        1:'Monday',
    
        2:'Tuesday'
    
    }
    day_name = switcher.get(day,'Unknow')
    
    print(day_name)

    利用get()完整模拟。

    在字典中模拟带函数的switch:

    day = 6
    
    
    def get_sunday():
    
        return 'Sunday'
    
     
    
    def get_monday():
    
        return 'Monday'
    
     
    
    def get_tuesday():
    
        return 'Tuesday'
     
    
    def get_default():
    
        return 'Unknow'
     
    
    switcher = {
    
        0:get_sunday,
    
        1:get_monday,
    
        2:get_tuesday
    
    }
    
    day_name = switcher.get(day,get_default)()
    
    print(day_name)

    二.列表推导式

    根据已经存在的列表创建新的列表:

    a = [1,2,3,4,5,6,7,8]

    b = [i * i for i in a]

    print(b)

    #[1, 4, 9, 16, 25, 36, 49, 64]

    或者i**2也事代表i的平方。

    条件筛选:用列表推导式

    a = [1,2,3,4,5,6,7,8]

    b = [i**2 for i in a if i >= 5]

    print(b)

    #[25, 36, 49, 64]

    map要结合filter才能实现。

    a是集合、字典、元组也可以被推导:

    a = {1,2,3,4,5,6,7,8}

    b = {i**2 for i in a if i >= 5}

    print(b)

    三. 字典如何编写列表推导式

    tudents = {
    
        'tai':18,
    
        'park':32,
    
        'a':12
    
    }
    
    b = [key for key,value in students.items()]
    
    print(b)
    
     
    
    students = {
    
        'tai':18,
    
        'park':32,
    
        'a':12
    
    }
    
    b = {value:key for key,value in students.items()}
    
    print(b)
    
    students = {
    
        'tai':18,
    
        'park':32,
    
        'a':12
    
    }
    
    b = (key for key,value in students.items())
    
    for x in b:
    
    print(x)

    四. iterator与generator

    迭代器:

    可迭代对象和迭代器

    可迭代对象(iterable):可被for in循环遍历的对象

    迭代器(iterator):是一个对象,可被for in循环遍历。一定是个可迭代对象。

    普通对象变成迭代器需要实现__iter__()和__next__():

    class BookCollection:
    
        def __init__(self):
    
            self.data = ['《往事》','《只能》','《回味》']
    
            self.cur = 0
    
    
        def __iter__(self):
    
            return self
    
    
        def __next__(self):
    
            if self.cur >= len(self.data):
    
                raise StopIteration()
    
            r = self.data[self.cur]
    
            self.cur += 1
    
            return r
    
    
    books = BookCollection()
    
    for book in books:
    
    print(book)

    除了for in 遍历,还可以调用next方法:

    books = BookCollection()

    print(next(books))

    print(next(books))

    print(next(books))

    迭代器具有一次性,只能遍历一次。若想再次遍历需要实例化一个新的对象。或者:

    import copy

    books = BookCollection()

    books_copy = copy.copy(books)    #浅拷贝

    若想实现深拷贝的话:

    books = BookCollection()

    books_copy = copy.deepcopy(books)    #生成器

    生成器:

    打印从0-10000的数字:

    n = [i for i in range(0,10001)]

    for i in n :

        print(i)

    可以实现但是太消耗内存。n是一个列表,列表存储需要消耗内存的。

    更好的方法:生成器

    迭代器是针对一个对象的,生成器是针对一个函数的。

    函数实现法:

    def gen(max):

        n = 0

        while n <= max:

            print(n)

            n += 1

    gen(100000)

    每次打印的都是实时计算出来的结果,不是都存储起来再打印。

    不应该在函数内部实现如print这样的操作。

    生成器:

    def gen(max):

        n = 0

        while n <= max:

            n += 1

            yield n

    g = gen(100000)

    next(g)

    next(g)

    for i in g:

        print(i)

    yield会接着返回的地方继续执行。

    n = (i for i in range(0,10001))

    此时n也为生成器。

    五. None

    None 空,不等于空字符串、空列表、0、False

    不仅在类型上不同,而且在值的比较上也不相同。

    class NoneType

    判空操作:

    def fun():

        return None

    a = fun()

    if not a:

        print('s')

    else:

        print('f')

    if a is None:

        print('s')

    else:

        print('f')

    #s

    #s

    如果 a = []则会进入到不同的分支中去。

    推荐if a/if not a来判空。

    None 不存在,False 假 

    14-7 对象存在并不一定是True

    None永远对应False

    自定义的对象:

    class Test():

        def __len__(self):

            return 0

    test = Test()

    if test:

        print('s')

    else:

        print('f')

    #f    #进的是False分支

    test存在也有可能是False,需要考虑__len__与__bool__方法。

    14-8 __len__与__bool__内置方法

    如果没有定义__len__与__bool__方法则默认为True。

    __len__返回0则为False,__len__代表长度,只能用int返回。

    例外:__len__可返回True和False

    调用len()时,则会调用__len__,如果没有__len__,求长度的时候会报错。

    一旦加入了__bool__则由__bool__来控制对象的取值。

    __bool__只能返回布尔型。

    六.装饰器的副作用

    import time
    
    def decorator(func):
    
        def wrapper():
    
            print(time.time())
    
            func()
    
        return wrapper
    
    #@decorator
    
    def f1():
    
        print(f1.__name__)
    
    
    f1()
    
    #f1            #不加装饰器的函数名字
    import time
    
    def decorator(func):
    
        def wrapper():
    
            print(time.time())
    
            func()
    
        return wrapper
    
    @decorator
    
    def f1():
    
        print(f1.__name__)
    
    f1()
    
    #1532492964.0116718
    
    #wrapper    #加装饰器的函数名字

    wrapper来字闭包函数。

    python->help(len)->打印出内置说明

    我们可以通过注释书写help()的内容

    加了装饰器之后就无法找到函数的help()了

    保证名字不改变:

    import time
    
    from functools import wraps
    
     
    
    def decorator(func):
    
        @wraps(func)
    
        def wrapper():
    
            print(time.time())
    
            func()
    
        return wrapper
    
     
    
    @decorator
    
    def f1():
    
        print(f1.__name__)
    
     
    
    f1()
    
    #1532493245.2623913
    
    #f1

    wraps传入了原有函数,所以得知了原函数的信息,然后复制到闭包函数上,则信息得以保存。

  • 相关阅读:
    hdu2089 数位dp
    AIM Tech Round 3 (Div. 2)
    Codeforces Round #372 (Div. 2)
    src 小心得
    水平文字垂直居中
    点击验证码刷新(tp3.1)--超简单
    TP3.1 中URL和APP区别
    getField方法
    PHP截取中文无乱码函数——cutstr
    substr — 详解
  • 原文地址:https://www.cnblogs.com/wlgaojin/p/12304788.html
Copyright © 2020-2023  润新知