zoukankan      html  css  js  c++  java
  • Python知识查漏补缺

    1.Python传参之 * /

    Keyword-only argument 是一种只能通过关键字指定而不能通过位置指定的参数。这迫使调用者必须指明,这个值是传给哪一个参数的。在函数的参数列表中,这种参数位于 * 符号的右侧。
    Positional-only argument 是这样一种参数,它不允许调用者通过关键字来指定,而是要求必须按位置传递。这可以降低调用代码与参数名称之间的耦合程度。在函数的参数列表中,这些参数位于 / 符号的左侧。
    在参数列表中, 位于 / 与 * 之间的参数,可以按位置指定,也可以用关键字来指定。这也是Python普通参数的默认指定方式。
    注:以上特性由python3.8引入

    2.Python推导式的使用原则

    常见的有列表推导式、字典推导式
    列表推导式:

    a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    squares = [i**2 for i in a]
    
    even_squares = [i**2 for i in a if i % 2 == 0]
    

    一些原则:

    1. 控制推导逻辑的子表达式不要超过两个
    matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    flat_matrix = [i for row in matrix for i in row]
    
    1. 推导的时候每层循环可以使用多个if条件,如果这些if条件在同一层循环内,那么他们之间默认是and关系。
    2. 考虑使用生成器表达式改写数据量较大的列表推导
    it = (len(i) for i in range(100000))
    

    返回的it为一个迭代器,可以使用next(it)取得其中的数据
    当然,生成器表达式还有另外一个强大的功能,就是可以组合使用,比如使用刚才生成器表达式返回的it作为输入,编写一条新的生成器表达式:

    roots = ((x, x**0.5 for x in it))
    

    这条生成器表达式形成的roots迭代器每次遍历时候,会引发连锁反应:它也推进内部迭代器it以判断是否还能在it上继续迭代,如果可以,就把it所返回的值传入(x, x**0.5)里面求出结果。
    注:需要注意的是生成器表达式返回的生成器即迭代器是有状态的,跑完一轮之后,就不能继续使用了,需要重新生成才能再次使用。
    4. 通过yield from 把多个生成器连接起来使用
    多个生成器连续使用时候一般我们可以这么做:
    例子:编写一个图形程序,让他在屏幕上移动,从而形成动画效果,假设实现这么一段动画,图片先快速移动一段时间,然后暂停,接下来慢速移动一段时间,为了把移动和暂停表示出来,可以定义下面两个生成器函数,让他们分别给出图片在当前时间内时间段内应该保持的速度

    def move(period, speed):
        for _ in range(period):
            yield speed
    def pause(period):
        for _ in range(period):
            yield 0
    def animate():
        for delta in move(4, 5.0):
            yield delta
        for delta in pause(3):
            yield delta
        for delta in move(2, 3.0):
            yield delta
    def render(delta):
        print(f'Delta: {delta:.1f}')
    def run(func):
        for delta in func():
            render(delta)
    if __name__ == '__main__':
        run(animate)
    # Delta: 5.0
    # Delta: 5.0
    # Delta: 5.0
    # Delta: 5.0
    # Delta: 0.0
    # Delta: 0.0
    # Delta: 0.0
    # Delta: 3.0
    # Delta: 3.0
    

    这种写法问题在于,animate函数里有很多重复的地方,代码比较繁琐。解决此问题可以使用yield from来实现

    def animate_composed():
      yield from move(4, 5.0)
      yield from pause(3)
      yield from move(2, 3.0)
    
    run(animate_composed)
    # 结果相同
    

    使用yield from的好处在于代码看上去更清晰、直观。同时yield from的速度更快,相比较普通yield语句的for循环速度
    接下来使用python内置的timeit模块编写运行一个micro-benchmark来测试下两者速度差别:

    import timeit
    def child():
        for i in range(1_000_000):
            yield i
    
    def slow():
        for i in child():
            yield i
    
    def fast():
        yield from child()
    
    def run_comparison():
        baseline = timeit.timeit(
            stmt='for _ in slow(): pass',
            globals=globals(),
            number=50
        )
        print(f'Manual nesting {baseline:.2f}s')
        comparison = timeit.timeit(
            stmt='for _ in fast(): pass',
            globals=globals(),
            number=50
        )
        print(f'Composed nesting {comparison:.2f}s')
        reduction = -(comparison - baseline) / baseline
        print(f'{reduction:.1%} less time')
    
    if __name__ == '__main__':
        run_comparison()
    # Manual nesting 2.41s
    # Composed nesting 2.29s
    # 5.0% less time
    

    请相信自己

    当我们迷茫,懒惰,退缩的时候 我们会格外的相信命运 相信一切都是命中注定

    而当我们努力拼搏,积极向上时 我们会格外的相信自己

    所以命运是什么呢? 它是如果你习惯它 那它就会一直左右你

    如果你想挣脱它 那它就成为你的阻碍 可如果你打破了它 那它就是你人生的垫脚石!


    如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!

  • 相关阅读:
    PostgreSQL远端访问
    PostgreSQL在线安装
    /usr/lib64改名字风波
    Provisional headers are shown(一)
    解析URL中的携带的参数到Map
    Mysql5.7的初始密码更改
    REST开放接口生成文档工具之apidoc
    自己来实现一套IOC注解框架
    RecyclerView打造通用的万能Adapter
    RecyclerView分隔线定制
  • 原文地址:https://www.cnblogs.com/suguangti/p/14970214.html
Copyright © 2011-2022 走看看