zoukankan      html  css  js  c++  java
  • Python 学习笔记二

    高级特性

    切片

    如果想取数组中的部分元素,则可以通过在数组中使用 [start:end] 实现,类似于JavaScript中的 slice(start, end);其中start和end都可以为负数,表示以倒数的方式来计算,也可以只写一个负数,也可以什么都不写只有一个:,表示复制整个数组。

    如果是::,表明每隔一段来取一个,比如:

    >>> 'ABCDEFG'[::2]
    'ACEG'
    
    

    也可以这么写,前6个数每2个取1个:

    >>> 'ABCDEFG'[:6:2]
    'BDF'
    
    

    切片适用于类似数组的类型,比如 字符串,list,tuple等等。

    迭代

    在python中,迭代使用的是for...in...关键字,同时只要是可迭代对象,都可以迭代,比如json对象等等。

    那么,如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断:

    >>> from collections import Iterable
    >>> isinstance('abc', Iterable) # str是否可迭代
    True
    >>> isinstance([1,2,3], Iterable) # list是否可迭代
    True
    >>> isinstance(123, Iterable) # 整数是否可迭代
    False
    
    

    列表生成式

    将所有的表达式放到[]里面去执行:

    >>> [x * x for x in range(1, 11) if x % 2 == 0]
    [4, 16, 36, 64, 100]
    
    

    生成器

    怎么创建一个生成器呢?

    1. 列表生成式中外围的[]改为()即可

      可以通过next函数获取generator的下一个返回值。

      >>> L = [x * x for x in range(10)]
      >>> L
      [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
      >>> g = (x * x for x in range(10))
      >>> g
      <generator object <genexpr> at 0x1022ef630>
      
      >>> next(g)
      0
      >>> next(g)
      1
      
      
    2. 在函数中使用yield关键字,其作用类似于return+print

      def odd():
          print('step 1')
          yield 1
          print('step 2')
          yield(3)
          print('step 3')
          yield(5)
      
      

      在执行过next后,再次执行的时候则从上一次执行yield后的位置继续执行,遇见yield则返回,但是如果执行到后面已经没有yield后,则会报错。

      >>> o = odd()
      >>> next(o)
      step 1
      1
      >>> next(o)
      step 2
      3
      >>> next(o)
      step 3
      5
      

      如果不想用next,一步一步的计算,同样的可以使用循环。

      def fib(max):
          n, a, b = 0, 0, 1
          while n < max:
              yield b
              a, b = b, a + b
              n = n + 1
          return 'done'
          
      >>> for n in fib(6):
      ...     print(n)
      ...
      1
      1
      2
      3
      5
      8
      
      

      如果想要捕捉到返回值,则在找不到next的时候(异常)返回,例如:

      >>> g = fib(6)
      >>> while True:
      ...     try:
      ...         x = next(g)
      ...         print('g:', x)
      ...     except StopIteration as e:
      ...         print('Generator return value:', e.value)
      ...         break
      ...
      g: 1
      g: 1
      g: 2
      g: 3
      g: 5
      g: 8
      Generator return value: done
      
      

    迭代器

    注意区分 Iterable和Iterator,前者是可迭代的,后者是迭代器(类似于C++中vector和::iterator),同样的,可以使用isinstance来判断;

    函数式编程

    高阶函数

    map/reduce

    map(函数,Iterable),将可迭代对象中的元素执行函数以后生成一个新的iterator;

    >>> def f(x):
    ...     return x * x
    ...
    >>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
    >>> list(r)
    [1, 4, 9, 16, 25, 36, 49, 64, 81]
    
    

    reduce函数必须接收两个参数,一个是函数,一个是list,其重点在于将list中的元素进行函数计算后作用到下一个元素上。

    reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
    
    

    比如这么用:

    from functools import reduce
    
    def str2int(s):
        def fn(x, y):
            return x * 10 + y
        def char2num(s):
            return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
        return reduce(fn, map(char2num, s))
        
    

    filter

    用于过滤序列,返回一个新的序列;

    map一样,同样接收一个函数和序列,但不同的是,filter使用函数对序列中的元素进行筛选,也就是说该函数是一个bool函数,将值传递进去后只有返回成功才将该值加入到新的队列中。

    def is_odd(n):
        return n % 2 == 1
    
    list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
    # 结果: [1, 5, 9, 15]
    
    

    如果这不是一个筛选函数呢?python则认为均为false,也就是不加入任何元素,返回空序列。

    sorted

    对序列进行排序,后面还可以加上key来指定排序函数,还可以加上reverse表示反向排序;

    class Student:
            def __init__(self, name, grade, age):
                    self.name = name
                    self.grade = grade
                    self.age = age
            def __repr__(self):
                    return repr((self.name, self.grade, self.age))
    
    # student_objects = [
    #        Student('john', 'A', 15),
    #        Student('jane', 'B', 12),
    #        Student('dave', 'B', 10),
    #]
    
    # 使用lambda
    sorted(student_objects, key=lambda student: student.age, reverse=True)   
    # sort by age
    # [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
    
    # 或者使用attrgetter
    sorted(student_objects, key=attrgetter('age'), reverse=True)
    
    

    闭包

    当你调用了一个函数A,这个函数A返回内部的函数B,这个返回的函数B就是闭包;

    def func(name):
        def inner_func(age):
            print 'name:', name, 'age:', age
        return inner_func
    
    bb = func('the5fire')
    bb(26)  # >>> name: the5fire age: 26
    
    

    匿名函数

    lambda表示匿名函数(和C++ 11.0中的lambda表达式类似),格式为:

    lambda x : x * x
    
    

    冒号前面表示参数,返回值为冒号后面的计算结果。

    装饰器

    需要单独写一篇文章进行总结(重要)

    总之就是在不改变一个函数的前提下(其它调用该函数的也不需要改变,只需要在调用函数前面加上@decorator就行),往该函数上加功能进行任意的扩展。

    偏函数

    functools.partial表示的是将函数“保存”下来,返回来一个在原来函数的基础上重新定义的函数;

    例子:

    import functools
    
    def add(a, b):
        return a + b
    
    add(4, 2)
    6
    
    plus3 = functools.partial(add, 3)
    plus5 = functools.partial(add, 5)
    
    plus3(4)
    7
    
    plus5(10)
    15
    
    

    除此之外,functools模块还包括:

    • functool.update_wrapper:从原始对象拷贝或加入现有partial对象
    • functool.wraps:调用函数装饰器partial
    • functools.reduce:等同于内置函数reduce()
    • functools.cmp_to_key:将老式鼻尖函数转换成key函数,用在接受key函数的方法中
    • functools.total_ordering:它是针对某个类如果定义了__lt__、le、gt、__ge__这些方法中的至少一个,使用该装饰器,则会自动的把其他几个比较函数也实现在该类中。

    面向对象编程

    继承和多态

    对于静态语言(例如Java)来说,如果需要传入Animal类型,则传入的对象必须是Animal类型或者它的子类,否则,将无法调用run()方法。

    对于Python这样的动态语言来说,则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了:

    实例属性和类属性

    在编写程序的时候,千万不要把实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性,但是当你删除实例属性后,再使用相同的名称,访问到的将是类属性,个人不建议在示例上添加任何新的属性,在类中加上属性即可。

  • 相关阅读:
    创业团队的狼性管理:慈不掌兵 义不聚财
    爱德华·斯诺登
    塞班岛
    大兴雷克萨斯深度剖析2013款LS460L_深圳大兴雷克萨斯_太平洋汽车网
    金字塔底端_百度百科
    左立_百度百科
    志大才疏_百度百科
    JS~json日期格式化
    MVVM架构~knockoutjs系列之从Knockout.Validation.js源码中学习它的用法
    JS~重写alter与confirm,让它们变成fancybox风格
  • 原文地址:https://www.cnblogs.com/George1994/p/6743294.html
Copyright © 2011-2022 走看看