python 知识回顾

Posted 风水涣

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 知识回顾相关的知识,希望对你有一定的参考价值。

 

 

一 数据类型

1 数字

整型与浮点型

 
#整型int
  作用:年纪,等级,身份证号,qq号等整型数字相关
  定义:
    age=10 #本质age=int(10)

#浮点型float
  作用:薪资,身高,体重,体质参数等浮点数相关

    salary=3000.3 #本质salary=float(3000.3)

#二进制,十进制,八进制,十六进制 
 

其他数字类型(了解)

 
#长整形(了解)
    在python2中(python3中没有长整形的概念):      
    >>> num=2L
    >>> type(num)
    <type \'long\'>

#复数(了解)  
    >>> x=1-2j
    >>> x.real
    1.0
    >>> x.imag
    -2.0  
 
 

2 字符串

 
#作用:名字,性别,国籍,地址等描述信息

#定义:在单引号\\双引号\\三引号内,由一串字符组成
name=\'egon\'

#优先掌握的操作:
按索引取值(正向取+反向取) :只能取
切片(顾头不顾尾,步长)
长度len
成员运算in和not in

移除空白strip 切分split
循环
 

 

3 列表

 
#作用:多个装备,多个爱好,多门课程,多个女朋友等

#定义:[]内可以有多个任意类型的值,逗号分隔
my_girl_friends=[\'laoyi\',\'laoer\',\'laosan\',4,5] #本质my_girl_friends=list([...])
或
l=list(\'abc\')

#优先掌握的操作:
按索引存取值(正向存取+反向存取):即可存也可以取      
切片(顾头不顾尾,步长)
长度
成员运算in和not in

追加 删除 循环
 
 
#ps:反向步长
l=[1,2,3,4,5,6]

#正向步长
l[0:3:1] #[1, 2, 3]
#反向步长
l[2::-1] #[3, 2, 1]
#列表翻转
l[::-1] #[6, 5, 4, 3, 2, 1]
 

 

4 元组

 
#作用:存多个值,对比列表来说,元组不可变(是可以当做字典的key的),主要是用来读

#定义:与列表类型比,只不过[]换成()
age=(11,22,33,44,55)本质age=tuple((11,22,33,44,55))

#优先掌握的操作:
按索引取值(正向取+反向取):只能取   
切片(顾头不顾尾,步长)
长度
成员运算in和not in


循环
 

 

5 字典

 
#作用:存多个值,key-value存取,取值速度快

#定义:key必须是不可变类型,value可以是任意类型
info={\'name\':\'laoyi\',\'age\':18,\'sex\':\'male\'} #本质info=dict({....})
或
info=dict(name=\'laoyi\',age=18,sex=\'male\')
或
info=dict([[\'name\',\'laoyi\'],(\'age\',18)])
或
{}.fromkeys((\'name\',\'age\',\'sex\'),None)

#优先掌握的操作:
按key存取值:可存可取
长度len
成员运算in和not in


删除
键keys(),值values(),键值对items()
循环
 

 



#利用setdefault解决重复赋值
\'\'\'
setdefault的功能
1:key存在,则不赋值,key不存在则设置默认值
2:key存在,返回的是key对应的已有的值,key不存在,返回的则是要设置的默认值
d={}
print(d.setdefault(\'a\',1)) #返回1

d={\'a\':2222}
print(d.setdefault(\'a\',1)) #返回2222
\'\'\'
s=\'hello alex alex say hello sb sb\'
dic={}
words=s.split()
for word in words: #word=\'alex\'
    dic.setdefault(word,s.count(word))
    print(dic)



#利用集合,去掉重复,减少循环次数
s=\'hello laoda laoda say hello sb sb\'
dic={}
words=s.split()
words_set=set(words)
for word in words_set:
    dic[word]=s.count(word)
    print(dic)
 
 

6 集合 

 
#作用:去重,关系运算,

#定义:
            知识点回顾
            可变类型是不可hash类型
            不可变类型是可hash类型

#定义集合:
            集合:可以包含多个元素,用逗号分割,
            集合的元素遵循三个原则:
             1:每个元素必须是不可变类型(可hash,可作为字典的key)
             2:没有重复的元素
             3:无序

注意集合的目的是将不同的值存放到一起,不同的集合间用来做关系运算,无需纠结于集合中单个值
 

#优先掌握的操作:
长度len
成员运算in和not in


|合集
&交集
-差集
^对称差集
==
>,>= ,<,<= 父集,子集           
 

 

7 数据类型总结

按存储空间的占用分(从低到高)

数字
字符串
集合:无序,即无序存索引相关信息
元组:有序,需要存索引相关信息,不可变
列表:有序,需要存索引相关信息,可变,需要处理数据的增删改
字典:无序,需要存key与value映射的相关信息,可变,需要处理数据的增删改

按存值个数区分

标量/原子类型 数字,字符串
容器类型 列表,元组,字典

 

 

按可变不可变区分

可变 列表,字典
不可变 数字,字符串,元组

 

 

按访问顺序区分

直接访问 数字
顺序访问(序列类型) 字符串,列表,元组
key值访问(映射类型) 字典

 

 

  

 

二 匿名函数

1. 什么是匿名函数?

 
匿名就是没有名字
def func(x,y,z=1):
    return x+y+z

匿名
lambda x,y,z=1:x+y+z #与函数有相同的作用域,但是匿名意味着引用计数为0,使用一次就释放,除非让其有名字
func=lambda x,y,z=1:x+y+z 
func(1,2,3)
#让其有名字就没有意义

匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。
 

2. 有名字的函数与匿名函数的对比

#有名函数与匿名函数的对比
有名函数:循环使用,保存了名字,通过名字就可以重复引用函数功能

匿名函数:一次性使用,随时随时定义

应用:max,min,sorted,map,reduce,filter
它语法简单,简化代码,不会产生命名冲突,污染命名空间。即用即抛。
 

三 闭包,装饰器、生成器、迭代器

闭包

一 什么是闭包?
 
#内部函数包含对外部作用域而非全局作用域的引用

#提示:之前我们都是通过参数将外部的值传给函数,闭包提供了另外一种思路

        def counter():
            n=0
            def incr():
                nonlocal n
                x=n
                n+=1
                return x
            return incr

        c=counter()
        print(c())
        print(c())
        print(c())
        print(c.__closure__[0].cell_contents) #查看闭包的元素
 
二 闭包的意义与应用
 
#闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域
#应用领域:延迟计算(原来我们是传参,现在我们是包起来)
    from urllib.request import urlopen

    def index(url):
        def get():
            return urlopen(url).read()
        return get

    baidu=index(\'http://www.baidu.com\')
    print(baidu().decode(\'utf-8\'))
 

装饰器

装饰器就是闭包函数的一种应用场景

1 为何要用装饰器
#开放封闭原则:对修改封闭,对扩展开放
2 什么是装饰器
装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。
强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式
装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能
3 装饰器的使用
import time
def timmer(func):
    def wrapper(*args,**kwargs):
        start_time=time.time()
        res=func(*args,**kwargs)
        stop_time=time.time()
        print(\'run time is %s\' %(stop_time-start_time))
        return res
    return wrapper

@timmer
def foo():
    time.sleep(3)
    print(\'from foo\')
foo()
无参装饰器
def auth(driver=\'file\'):
    def auth2(func):
        def wrapper(*args,**kwargs):
            name=input("user: ")
            pwd=input("pwd: ")

            if driver == \'file\':
                if name == \'egon\' and pwd == \'123\':
                    print(\'login successful\')
                    res=func(*args,**kwargs)
                    return res
            elif driver == \'ldap\':
                print(\'ldap\')
        return wrapper
    return auth2

@auth(driver=\'file\')
def foo(name):
    print(name)

foo(\'egon\')
有参装饰器

 

4 装饰器语法
 
被装饰函数的正上方,单独一行
        @deco1
        @deco2
        @deco3
        def foo():
            pass

        foo=deco1(deco2(deco3(foo)))
 
5 装饰器补充:wraps
 
from functools import wraps

def deco(func):
    @wraps(func) #加在最内层函数正上方
    def wrapper(*args,**kwargs):
        return func(*args,**kwargs)
    return wrapper

@deco
def index():
    \'\'\'哈哈哈哈\'\'\'
    print(\'from index\')

print(index.__doc__)
 

迭代器

1 迭代的概念

 
#迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值
while True: #只是单纯地重复,因而不是迭代
    print(\'===>\') 
    
l=[1,2,3]
count=0
while count < len(l): #迭代
    print(l[count])
    count+=1
 

2 为何要有迭代器?什么是可迭代对象?什么是迭代器对象?


#1、为何要有迭代器?
对于序列类型:字符串、列表、元组,我们可以使用索引的方式迭代取出其包含的元素。但对于字典、集合、文件等类型是没有索引的,若还想取出其内部包含的元素,则必须找出一种不依赖于索引的迭代方式,这就是迭代器

#2、什么是可迭代对象?
可迭代对象指的是内置有__iter__方法的对象,即obj.__iter__,如下
\'hello\'.__iter__
(1,2,3).__iter__
[1,2,3].__iter__
{\'a\':1}.__iter__
{\'a\',\'b\'}.__iter__
open(\'a.txt\').__iter__

#3、什么是迭代器对象?
可迭代对象执行obj.__iter__()得到的结果就是迭代器对象
而迭代器对象指的是即内置有__iter__又内置有__next__方法的对象

文件类型是迭代器对象
open(\'a.txt\').__iter__()
open(\'a.txt\').__next__()


#4、注意:
迭代器对象一定是可迭代对象,而可迭代对象不一定是迭代器对象
 

3 迭代器对象的使用


dic={\'a\':1,\'b\':2,\'c\':3}
iter_dic=dic.__iter__() #得到迭代器对象,迭代器对象即有__iter__又有__next__,但是:迭代器.__iter__()得到的仍然是迭代器本身
iter_dic.__iter__() is iter_dic #True

print(iter_dic.__next__()) #等同于next(iter_dic)
print(iter_dic.__next__()) #等同于next(iter_dic)
print(iter_dic.__next__()) #等同于next(iter_dic)
# print(iter_dic.__next__()) #抛出异常StopIteration,或者说结束标志

#有了迭代器,我们就可以不依赖索引迭代取值了
iter_dic=dic.__iter__()
while 1:
    try:
        k=next(iter_dic)
        print(dic[k])
    except StopIteration:
        break
        
#这么写太丑陋了,需要我们自己捕捉异常,控制next,python这么牛逼,能不能帮我解决呢?能,请看for循环
 

4 for循环

 
#基于for循环,我们可以完全不再依赖索引去取值了
dic={\'a\':1,\'b\':2,\'c\':3}
for k in dic:
    print(dic[k])

#for循环的工作原理
#1:执行in后对象的dic.__iter__()方法,得到一个迭代器对象iter_dic
#2: 执行next(iter_dic),将得到的值赋值给k,然后执行循环体代码
#3: 重复过程2,直到捕捉到异常StopIteration,结束循环
 

5 迭代器的优缺点

#优点:
  - 提供一种统一的、不依赖于索引的迭代方式
  - 惰性计算,节省内存
#缺点:
  - 无法获取长度(只有在next完毕才知道到底有几个值)
  - 一次性的,只能往后走,不能往前退

 生成器

1 什么是生成器

 
#只要函数内部包含有yield关键字,那么函数名()的到的结果就是生成器,并且不会执行函数内部代码

def func():
    print(\'====>first\')
    yield 1
    print(\'====>second\')
    yield 2
    print(\'====>third\')
    yield 3
    print(\'====>end\')

g=func()
print(g) #<generator object func at 0x0000000002184360> 
 

2 生成器就是迭代器

g.__iter__
g.__next__
#2、所以生成器就是迭代器,因此可以这么取值
res=next(g)
print(res)

3 生成器表达式

 
#1、把列表推导式的[]换成()就是生成器表达式

#2、示例:生一筐鸡蛋变成给你一只老母鸡,用的时候就下蛋,这也是生成器的特性
>>> chicken=(\'鸡蛋%s\' %i for i in range(5))
>>> chicken
<generator object <genexpr> at 0x10143f200>
>>> next(chicken)
\'鸡蛋0\'
>>> list(chicken) #因chicken可迭代,因而可以转成列表
[\'鸡蛋1\', \'鸡蛋2\', \'鸡蛋3\', \'鸡蛋4\',]

#3、优点:省内存,一次只产生一个值在内存中
 

四 内置函数、高阶函数

内置函数 参考:https://docs.python.org/3/library/functions.html?highlight=built#ascii

高阶函数

sorted

  排序算法


排序也是在程序中经常用到的算法。无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小。
如果是数字,我们可以直接比较,但如果是字符串或者两个dict呢?直接比较数学上的大小是没有意义的,因此,比较的过程必须通过函数抽象出来。
通常规定,对于两个元素x和y,如果认为x < y,则返回-1,如果认为x == y,则返回0,如果认为x > y,则返回1,这样,排序算法就不用关心具体的比较过程,而是根据比较结果直接排序。 Python内置的sorted()函数就可以对list进行排序: >>> sorted([36, 5, 12, 9, 21]) [5, 9, 12, 21, 36] 此外,sorted()函数也是一个高阶函数,它还可以接收一个比较函数来实现自定义的排序。比如,如果要倒序排序,我们就可以自定义一个reversed_cmp函数: def reversed_cmp(x, y): if x > y: return -1 if x < y: return 1 return 0 传入自定义的比较函数reversed_cmp,就可以实现倒序排序: >>> sorted([36, 5, 12, 9, 21], reversed_cmp) [36, 21, 12, 9, 5] 我们再看一个字符串排序的例子: >>> sorted([\'bob\', \'about\', \'Zoo\', \'Credit\']) [\'Credit\', \'Zoo\', \'about\', \'bob\'] 默认情况下,对字符串排序,是按照ASCII的大小比较的,由于\'Z\' < \'a\',结果,大写字母Z会排在小写字母a的前面。 现在,我们提出排序应该忽略大小写,按照字母序排序。要实现这个算法,不必对现有代码大加改动,只要我们能定义出忽略大小写的比较算法就可以: def cmp_ignore_case(s1, s2): u1 = s1.upper() u2 = s2.upper() if u1 < u2: return -1 if u1 > u2: return 1 return 0 忽略大小写来比较两个字符串,实际上就是先把字符串都变成大写(或者都变成小写),再比较。 这样,我们给sorted传入上述比较函数,即可实现忽略大小写的排序: >>> sorted([\'bob\', \'about\', \'Zoo\', \'Credit\'], cmp_ignore_case) [\'about\', \'bob\', \'Credit\', \'Zoo\'] 从上述例子可以看出,高阶函数的抽象能力是非常强大的,而且,核心代码可以保持得非常简洁。

 

 

map/reduce

map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。
举例说明,比如我们有一个函数f(x)=x2,要把这个函数作用在一个list [1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map()实现如下:
现在,我们用Python代码实现:
>>> 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]
map()传入的第一个参数是f,即函数对象本身。由于结果r是一个Iterator,Iterator是惰性序列,因此通过list()函数让它把整个序列都计算出来并返回一个list。
L = []
for n in [1, 2, 3, 4, 5, 6, 7, 8, 9]:
    L.append(f(n))
print(L)

map()作为高阶函数,事实上它把运算规则抽象了,因此,我们不但可以计算简单的f(x)=x2,还可以计算任意复杂的函数,比如,把这个list所有数字转为字符串:

>>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
[\'1\', \'2\', \'3\', \'4\', \'5\', \'6\', \'7\', \'8\', \'9\']

再看reduce的用法。reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
比方说对一个序列求和,就可以用reduce实现:
>>> from functools import reduce
>>> def add(x, y):
...     return x + y
...
>>> reduce(add, [1, 3, 5, 7, 9])
25
当然求和运算可以直接用Python内建函数sum(),没必要动用reduce。

但是如果要把序列[1, 3, 5, 7, 9]变换成整数13579,reduce就可以派上用场:

>>> from functools import reduce
>>> def fn(x, y):
...     return x * 10 + y
...
>>> reduce(fn, [1, 3, 5, 7, 9])
13579

这个例子本身没多大用处,但是,如果考虑到字符串str也是一个序列,对上面的例子稍加改动,配合map(),我们就可以写出把str转换为int的函数:

>>> from functools import reduce
>>> 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]
...
>>> reduce(fn, map(char2num, \'13579\'))
13579

整理成一个str2int的函数就是:

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))

还可以用lambda函数进一步简化成:

from functools import reduce

def char2num(s):
    return {\'0\'以上是关于python 知识回顾的主要内容,如果未能解决你的问题,请参考以下文章

python 知识回顾

Python+pytest知识点回顾

Python学习第97天(MySQL知识回顾)

Python学习第97天(MySQL知识回顾)

Python + unittest知识点回顾

Python序列应用知识回顾