[学习总结] python语言学习总结 (二)

1.python中的拆包

之前就只写了*可以是未知数量的参数,**可以传入未知数量命名参数。这次详细记下拆包。

def f1(a, *l):
    print(a)
    # 不拆包
    print(l)
    # 拆包
    print(*l)
    f2(l)
    f2(*l)


def f2(*l):
    print(l)
    print(*l)


def f3(**kw):
    # 不拆包
    print(kw)
    # 得到键名
    print(*kw)
    # 拆包,键名对应
    f4(**kw)
    # 注意,python中没办法输出**kw,不信可以自己试试。。


def f4(a, b):
    print(a, b)


f3(a=1, b=2)


f1(1, 2, 3)

'''
{'a': 1, 'b': 2}
a b
1 2
1
(2, 3)
2 3
((2, 3),)
(2, 3)
(2, 3)
2 3
'''

我试图通过这段代码的运行情况搞清楚拆包,实际上结果也特别明显。

其实python给f1和f2函数传入的参数是个元组,也就是形式参数被转换为元组传入了f1和f2中作为实参,这应该是函数给我们做的装包工作,这个工作对我们在函数里操作是很方便的,而从未拆包和拆包的f2的输出来看,我们的理解是正确的。

同样的,**kw传入的参数其实是个字典,传入之后会隐式地进行装包工作,也就是将a=1,b=2装包成{'a':1,'b':2}的字典,这样方便了我们在函数中提取相应参数,我觉得还是很有用的。需要注意的是,我们无法通过print(**kw)得到a=1,b=2的输出结果,因为print函数貌似不支持这种输出,可以自己尝试下。而从f4的输出看出,我们的理解是正确的。

因此,我们可以在以下场景用到拆包操作。

1.我们有一个元组,想把这个元组的数据分别作为参数传入。其实就是上面f2函数实现的。

2.我们有一个字典,想把这个字典的数据分别作为参数传入。其实就是上面f4函数实现的。

2.python中的切片

说实在话,切片用到的次数非常多,因为经常操作字符串、list和numpy,所以这个东西用到的次数非常多。

以一个简单的字符串为例

str = "abcdefg"


print(str[0:2:1], str[0:2:-1], str[:], str[::-1], str[::-2])


'''
ab  abcdefg gfedcba geca
'''

切片最常用的是一个左右中括号的操作;通过指定的下标来访问一组序列的元素,其实就切片操作。

中括号中我们可以指定三个参数,其中第一个参数代表要取的序列的起始index,我们选0,就是从最开始选,第二个参数是结束index,但是不包含这个index对应的数据,从以上输出中我们是可以看出来的,第三个参数是步长,步长为1,那么他就从左往右一个一个取;步长为-1,那么他就从右往左一个一个取,步长为负就是反方向取,因此我们可以填-2,那么他就从右往左以两个步长取元素。

其中呢,后面的冒号是可以省略的,也就是可以不填步长,默认就是1,只有一个冒号而不填任何参数就是复制这个序列,而前两个参数空,只把步长设为1其实就是倒置这个序列。

3.python中的名称空间

python中的名称空间我觉得还是要搞清楚的,这样对理解python这门语言还是很有帮助的。
名称空间(namespace):名称空间是名字和对象的映射。也就是可以把一个namespace理解为一个字典,实际上很多当前的Python实现namespace就是用的字典。各个名称空间是独立的,没有任何关系的,所以一个名称空间中不能有重名,但不同的名称空间是可以重名而没有任何影响。


Build-in
....Global
........Enclosed
............Local

可见确实是个层级关系。
我们来分别解释这四个名称空间,
Build-in:python解释器启动产生的字典,用于存放python内置的名字。
Global:执行python文件时,存放文件级定义的名字,就是被import的时候创建,在解释器退出的时候才被删除。
Enclosed:指的是一个函数被另一个函数包含时的命名空间。
Local:执行文件过程中,调用函数时产生的名称空间,用来存放函数内定义的名字,由于生命周期的原因,函数调用结束后该名字会被删除。

Python在查找变量时候按照从内至外的顺序查找变量,可以说成是LEGBD顺序。
作用域(scope):作用域是Python程序(文本)的某一段或某些段,在这些地方,某个命名空间中的名字可以被直接引用。这个作用域就是这个命名空间的作用域。

下面用代码来理解一下作用域。

from copy import copy
a = 5
print("***build-in and globals***")
#  print(type(list(globals().keys())))
globals_init = copy(list(globals().keys()))
print("\n".join(globals_init))  # 输出的是build-in的命名空间下的名字key


def f1(b=3):
    c = 4
    print("***globals in f1***", *(globals().keys() - globals_init), sep="\n")
    #  解释下这里,globals().keys()返回的是list,list相减得到的是set,然后对set解包就可以输出了,也可以把set转化为list用.join输出
    print("***locals in f1***", *(locals().keys()), sep="\n")
    
    
    def f2():
        c = 5
        print("***locals in f2***", *(locals().keys()), sep="\n")
    print("c=", c)
    f2()
    print("c=", c)


    def f3():
        nonlocal c
        c = 6
        print("***locals in f3***", *(locals().keys()), sep="\n")
    print("c=", c)
    f3()
    print("c=", c)


f1()

'''
***build-in and globals***
__name__
__doc__
__package__
__loader__
__spec__
__annotations__
__builtins__
__file__
__cached__
copy
a
***globals in f1***
globals_init
f1
***locals in f1***
b
c
c= 4
locals in f2
c
c= 4
c= 4
locals in f3
c
c= 6
'''

咱们从这里可以看出,不同作用域对应的名称是相互独立的,在函数内如果和函数外有相同的变量名称,会默认把近的那个作为要找到的变量,如果要访问函数外的比如a怎么办呢,很简单,函数里面写上global a 即可,否则你的操作就相当于在函数内的local里建立了一个新变量。函数嵌套的时候使用nonlocal去操作被套函数外的local变量,甚至也可以通过global操作全局变量。上面的例子仔细看看应该是理解了。

4.python中的一些高阶函数总结

分别是map、filter、reduce、sorted。其中sorted函数之前已经写过了,但是当时没有用到参数key,这次查了一下,发现key就是自定义排序规则,比如我们让key=abs,那么就会按照绝对值大小排序,当然我们也可以自定义函数,我这里用lambda定义了匿名函数来对x平方大小排序,然后映射回原list。map函数通过建立一个映射,对后面的range通过调用前面的匿名函数形成一个数值映射,然后得到map结果,我们将这个结果转为list输出。filter在map的基础上呢,相当于加上了一层判断,其实filter也会对后面的list生成一个值的映射,但是filter会利用函数作为参数做一层判断,保留满足条件的结果。reduce函数呢,可以允许我们两两调用函数参数,最终只得到一个结果(如例子),这个例子的计算结果其实是1*2*3*4=24也就是也就是先1*2=2,再2*3=6,再6*4=24的结果。;lambda没什么说的了。不是很全,后面会再总结。

from functools import reduce
import random
a = map(lambda x: x**2, range(1, 5))
print(list(a))
#  [1, 4, 9, 16]

b = filter(lambda x: x>0, [1,-5,6,0])
print(list(b))
#  [1, 6]

c = reduce(lambda x,y: x*y,range(1,5))
print(c)
#  24

lst = [x * (-1)**x for x in range(1,10)]
random.shuffle(lst)
print(lst)
d = sorted(lst,key = lambda x: x**2,reverse = True)
print(d)
#  [-3, -5, -7, 4, 6, 8, -1, 2, -9]
#  [-9, 8, -7, 6, -5, 4, -3, 2, -1]

猜你喜欢

转载自www.cnblogs.com/aoru45/p/9908590.html
今日推荐