2022年 11月 5日

Python一些常用方法

Python一些常用方法

(仅作为个人笔记,如有雷同,请联系删除。。)

1、常用方法:

求阶乘:reduce(lambda x,y:x*y, range(1, 101))

求和:sum(range(101))

合并字典:dict1.update(dict2)

去重:[x for x in set(listx)]

排序:listx.sort() | sorted(listx)

统计:collections.Counter(listx) | listx.count(argv)

zip(list1, list2, ......)

enumerate(listx)

dictx.items()、dictx.keys()、dictx.values()

format传参:
str = "helle, {1}, let's to {2}"``.format``(parm1, parm2)
str = f"helle, {parm1}, let's to {parm2}"

1+1、常用内置函数:

abs() dict() help() min() setattr()
all() dir() hex() next() slice()
any() divmod() id() object() sorted()
ascii() enumerate() input() oct() staticmethod()
bin() eval() int() open() str()
bool() exec() isinstance() ord() sum()
bytearray() filter() issubclass() pow() super()
bytes() float() iter() print() tuple()
callable() format() len() property() type()
chr() frozenset() list() range() vars()
classmethod() getattr() locals() repr() zip()
compile() globals() map() reversed() __import__()
complex() hasattr() max() round()
delattr() hash() memoryview() set()

2、三个内建函数:

  1. map(func, listx):listx中的值依次传入func,返回一个新的序列。eg:list(map(lambda x:x*x, range(1,10))

  2. filter(func, listx):listx中的值依次传入func,留下返回true的,构成一个新的序列。eg:list(filter(lambda x:x%2==0, range(100)))

  3. reduce(func, listx):func接收两个参数,listx中的值依次传入func,会对func的结果进行累积,作为下一次调用的一个参数,一般会以listx中的前两个值作为初始参数调用func,返回一个最终值.
    eg:reduce(lambda x,y:x*y, range(1, n+1))、 reduce(lambda x,y:x+y, range(10))

    注:python3已不支持,需要from functools import reduce

3、左移、右移:

  1. >>:一个数的二进制表示 向右移动一位,相当于干掉最后一位,奇数右移的结果为-1,÷2;偶数右移的结果为÷2

  2. <<:一个数的二进制表示 向左移动一位,相当于末位添0,结果是*2

4、魔法方法:

  1. __init__(self, ......):初始化方法,创建对象后,立刻被调用,用于设置类的各种属性

  2. __new__(cls)负责返回一个实例对象。

     **注:返回的不一定是当前类的对象,__new__(A),传入的是A,返回A类的实例对象。传入的不是本类cls,实例化一个对象,只会执行__new__(),不会自行__init__()
     
     	可以这样理解:实例化对象时,先__new__生成一个实例对象,再__init__初始化
    
    • 1
    • 2
    • 3
      def __new__(cls):
          return object.__new__(cls)   # 返回当前类的实例对象                             
  • 1
  • 2
  1. __str__:当使用print输出对象的时候,只要自定义了__str__(self)方法,就会打印从这个方法中return的数据

  2. __del__(self):删除对象执行的方法

5、迭代器、生成器、装饰器:

  1. 迭代器:for遍历的是可迭代对象[ Iterable ]。 iter(可迭代对象),返回一个迭代器[ Iterator ]
    迭代器是一个惰性序列,可以next(),不断返回下一个值。

  2. 生成器:generator,生成器表达式:(x * x for x in range(10)),即列表推导式的[]换成()
    生成器函数:普通函数中,用yield代替return,表明这是一个生成器函数。
    生成器也可以调用next()不断获取下一个返回值。[next,函数执行到yield便会停下来,返回一个值,直到下一次next,继续执行,执行到yield停下来,返回值。。。]

  3. 装饰器:在不修改现有函数的基础上,给其扩展额外的功能。且装饰器可复用,一个装饰器可修饰多个函数。
    装饰器引用了闭包思想,处理被其所修饰的函数,然后将该函数返回。
    闭包:嵌套函数,内部函数访问到外部函数中定义的变量,则内部函数称为闭包。

    # 定义装饰器
    from functools import wraps
    
    def decorator_name(func):
        @wraps(func)
        def decorated(*args, **kwargs):
            before doing
            # func(*args, **kwargs)
            # after doing
            return func(*args, **kwargs)
        return decorated
    
    # 使用装饰器
    @decorator_name
    def func():
        return("Function is running")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

6、空类型:

Python中,0、""、\[\]、{}、()、None、False,都被认为是False

type((1)) --> int
type(("1")) --> str
type((1,)) --> tuple
  • 1
  • 2
  • 3

7、实例方法、类方法、静态方法:

  1. 实例方法:第一个参数为self,表示一个具体的实例对象,只能被实例对象调用

    def instance_method(self):
    	print("实例方法")
    
    • 1
    • 2
  2. 类方法classmethod修饰,第一个参数为cls,用来修改类属性。模拟Java定义多个构造函数。可通过类名调用,可通过实例调用

    @classmethod
    def class_method(cls):
    	print("类方法")
    
    • 1
    • 2
    • 3
  3. 静态方法staticmethod修饰,没有参数要求,可用过类名调用,可通过实例调用,也可在本类中直接调用

    @staticmethod
    def static_method():
    	print("静态方法")
    
    • 1
    • 2
    • 3

8、数据类型、可变与不可变:

  • 不可变数据类型:数值型(int、float、bool、complex[复数])、str、tuple
  • 可变数据类型:list、dict、set

9、可变参数、关键字参数:【优先级:位置参数 > 默认参数 > 可变参数 > 可变关键字参数】

  1. 可变参数*args,表示任意多个参数,类型为tuple,可在函数中直接当做tuple去遍历等等;

  2. 可变关键字参数**kwargs,表示任意多个键值对参数,类型为dict,可在函数中直接当做dict去使用;

     注:在函数调用时,*会以单个元素的形式解包一个元祖,使其成为独立的参数,**会以键/值对的形式解包一个字典,使其成为独立的关键字参数。
    
    • 1

10、copy、deepcopy:

  1. 复制不可变数据类型[str、tuple、数值]:copy和deepcopy结果一样,和”=”赋值的情况相同,对象的id不变

    eg:
    a=7  
    a == copy.copy(a) == copy.deepcopy(a)
    
    • 1
    • 2
    • 3
  2. 复制可变数据类型[list、set、dict]:

    1. 对象中无复杂子对象[list中不嵌套list]:原对象的值改变,不会影响拷贝后对象。copy后是一个新的对象,id值与原对象不同
      eg: 
      listx = [1,2,3]
      listx != copy.copy(listx)
      listx != copy.deepcopy(listx)
      
      • 1
      • 2
      • 3
      • 4
    2. 对象中有复杂子对象[list中嵌套list]:
      1. copy浅拷贝,拷贝的是嵌套list的地址引用,原对象中嵌套list的值发生改变,拷贝后对象对随之发生改变;原对象中其他值改变,拷贝后对象不受影响。
        eg: 
        listx = [1,2,[3,4]]
        listy = copy.copy(listx)
        listx[2].append(7)
        listx.append(5)
        
        listx: [1,2,[3,4,7],5] 
        listy: [1,2,[3,4,7]]
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
      2. deepcopy深拷贝,完全复制独立,包括内层嵌套的list和dict,原对象发生改变,不影响拷贝后对象
        eg:
        listx = [1,2,[3,4]]
        listy = copy.deepcopy(listx)
        listx[2].append(7)
        listx.append(5)
        
        listx:  [1,2,[3,4,7],5]
        listy: [1,2,[3,4]]
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8

11、进程、线程:

在这里插入图片描述

  1. 进程操作系统分配资源的基本单位。多个进程之间相互独立,一个进程崩溃,不影响其他进程,但是进程消耗资源大,有数量限制。【多进程中每个进程都能被系统分配资源,相当于每个进程都有了一个python解释器】

  2. 线程CPU分配资源的基本单位。线程是进程的一部分,能够独立运行。一个进程下的多个线程可共享该进程的所有资源。但是,一个线程的崩溃,会造成整个进程的崩溃

  3. 协程:比线程更加轻量级的存在。正如一个进程可以拥有多个线程一样,一个线程也可以拥有多个协程。最重要的是,协程不是被操作系统内核所管理,而完全是由程序所控制(也就是在用户态执行)。这样带来的好处就是性能得到了很大的提升,不会像线程切换那样消耗资源

应用
IO操作密集,用多线程,在用户输入、sleep的时候,可以切换到其他线程执行,减少等待的时间。
CPU密集,用多进程,充分利用多核CPU的优势。

GILPython的全局解释器锁。同一个进程下,多个线程之间共享一个GIL,当前线程运行时会霸占GIL,其他线程无法运行,当遇到耗时操作,释放GIL,下一个线程运行。线程的运行是有先后顺序的,并非同时运行

from time import ctime, sleep

def loop(nloop, nsec):
    print("start loop", nloop, "at:", ctime())
    sleep(nsec)
    print("loop", nloop, "done at:", ctime())

if __name__=="__main__": 
    # 多进程
    from multiprocessing import Process
    p1 = Process(target=loop, args=(1, 4))
    p2 = Process(target=loop, args=(2, 3))
    p1.start()
    p2.start()
    p1.join()
    p2.join()
    
    
    ######################################################################################################
    # # 进程池:multiprocessing.Pool更加高级,可批量启动进程
    # from multiprocessing import Pool
    
    # pool = Pool(processes=3)
    # for i, j in zip([1, 2], [4, 3]):
    #     pool.apply_async(loop, args=(i, j))  # 维持执行的进程总数为processes,当一个进程执行完毕后会添加新的进程进去
    # pool.close()  # 调用join前,先调用close,表示不会有新的进程加入到pool,否则会出错。
    # pool.join()  # join等待所有子进程结束
    
    
    ######################################################################################################
    # # Python3标准库 concurrent.futures 模块提供了ProcessPoolExecutor (进程池)
    # from concurrent.futures import ProcessPoolExecutor
    
    # with ProcessPoolExecutor(max_workers=3) as executor:
    #     all_task = [executor.submit(loop, i, j) for i, j in zip([1, 2], [4, 3])]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
from time import sleep, ctime, time

def loop(nloop, nsec):
    print("start loop", nloop, "at:", ctime())
    sleep(nsec)
    print("loop", nloop, "done at:", ctime())

if __name__ == "__main__":
    # 多线程threading.Thread
    import threading
    threads = []  # 线程组
    for i, j in zip([1,2],[4,3]):
        t = threading.Thread(target=loop, args=(i, j))  # 线程分配
        threads.append(t)
    for t in threads:
        t.start()  # 线程开始执行
    for t in threads:
        t.join()  # 等待所有线程执行完成
    
    
    ##################################################################################################
    # # 线程池,更加高级,可批量启动进程
    # from multiprocessing.dummy import Pool
    
    # pool = Pool(processes=3)
    # for i, j in zip([1, 2], [4, 3]):
    #     pool.apply_async(loop, args=(i, j)) # 同进程池
    # pool.close() # 同进程池
    # pool.join()  # 同进程池
    
    
    ##################################################################################################
    # # Python3,标准库 concurrent.futures 模块提供了ThreadPoolExecutor (线程池)
    # from concurrent.futures import ThreadPoolExecutor
    
    # with ThreadPoolExecutor(max_workers=3) as executor:
    #     all_task = [executor.submit(loop, i, j) for i, j in zip([1, 2], [4, 3])]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

12、Python虚拟环境:pip install virtualenv

  1. virtualenv --no-site-packages --python=3.6 venv:创建虚拟环境
    指定不使用系统全局的site-packages中的第三方库。虚拟环境中的Python版本为3.6,虚拟环境名称为venv。

  2. source venv/bin/activate:激活虚拟环境

  3. pip install -r requirements.txt:安装当前工程依赖的第三方库

  4. deactivate:退出虚拟环境

13、py2和py3的区别:

python2 python3
print print “xxx” print(“xxx”)
input input() ——–> int
raw_input() —> str
input() —> str
/ / —> 整数相除,结果是整数;有小数,结果为小数
// —> 地板除,结果是整数
/ —> 结果是小数
// —> 地板除,结果是整数
range range(1,10) —> 返回list range(1,10) —> 返回迭代器,节约内存
循环 for i in xrange(10): —> 快 for i in range(10): —> 慢
编码 ASCII —> 要显示中文,需引入coding声明 utf-8 —> 可正常显示中文
字符串、字节 unicode表示字符串序列;
str表示字节序列
str表示字符串序列;
byte表示字节序列
异常捕获 except Exception, e: except Exception as e:
打开文件 file(…) open(…)

14、Python的垃圾回收机制:引用计数法

当有一个变量保存了对象的引用时,该对象的引用计数就会+1,当使用del删除变量指向的对象时,引用计数-1,直至引用计数为1时,再次调用del,彻底将该对象删除。

15、python传参是传值还是传址?—— 引用传递

16、选择排序和冒泡排序:

# 选择排序
list = [89,27,978,56,37,25]
for i in range(len(list)):	
    for j in range(i+1,len(list)):     # 每次循环取出最小值,放在第一位,第二位,。。。    
        if list[i] > list[j]:
            list[i],list[j] = list[j],list[i]
print(list) 

# 冒泡排序:
list = [89,27,978,56,37,25]
for i in range(len(list)-1):	          # 两两比较,只需要比较length-1次
    for j in range(0, len(list)-i-1):       # 每次循环,取出最大值,放到最后
        if list[j] > list[j+1]:
            list[j],list[j+1] = list[j+1],list[j]
print(list)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15