python(高级特性、高级函数、)

高级特性

走到这一步,就说明我们已经掌握了数据类型、语句以及函数。学到了这一步就说明我们,已经可以刷力扣题(熟练很重要的!!!加油,骚年。)了。接下来我们介绍一下高级的特性。

切片

我们经常遍历一些列表(数组),python怎么遍历呢?

需要注意的是,切片[ ]。主要的是区间的概念。到底是左开右闭还是什么什么,多试试就理解了。切片还可以,从右往左走。[ -10:-1]从右往左的话,起点是-1,不是零。

迭代

迭代对象。我们先看一下c语言的吧。

for(i=0:i<n:i++)

{

nun[i]=n;}

而python语言是通过迭代对象来遍历的。通过和c语言对比。会发现,python的for循环会更加抽象,比如说,最常见的是list和tuple,他们是有下表的,但是python也可以遍历没有下标的。比如说,dict。

从图中我们可以看见,迭代对象,dict默认的是value值,如果我们想要输出key值我们可以,

for key in a.keys():就可以了。

迭代对象也可以是字符串:

在Python中万物可对象,那如何判断某个对象可以迭代呢?

可以使用collections.abc模块的Iterable类型可以判如下:

我们是不是也可以做到像Java那样的下标循环。可以的。

列表生成器

python有好多语句可以使代码变得简洁。但是或许有些难理解,不过用多了自然就会了。

生成器

之前我们了解了list,相当于一个容器,里面放了好多元素。我们都知道,电脑的容量是有限的,list是不能无限大的。场景:有一个list,里面有很多元素。但是调用的元素就前几个元素。问题来了,是不是特别浪费内存。有没有一种方法节省空间呢。有的:生成器,生成器的原理就是一个公式。不会占用太大的空间。用的时候通过next()调用就可以了。

上图中的for循环有一点点问题。

对比一下两者有什么区别。自己去试一下。

我们可以看到,列表生成和生成器就是符号的差别。

注意:

这个报错是因为最后一个元素打印完了。问题不大,不需要管。

如果公式比较复杂,还可以使用函数。

这个函数是不是和generate很相似,只要我们把print B 改成 yield B 就是generator了。普通函数和generator逻辑上是不一样的。普通函数是按照顺序的结构走的,遇到return 或者是最后一句就返回了。而generator是遇到yield就返回,下一次,会从上次返回的节点继续走。

这是为什么呢?第二张图片。为什么一直打印第一个值呢?

因为通过for循环来遍历会产生三个对象。,每个相互独立的对象,只会输出一次。所以才有了这个现象。

迭代器

我们目前知道了for循环数据类型有以下几种。1、数据集合类型:list tuple dict set str 2、我们刚刚提到的生成器。generator的函数等。我们统称为可迭代对象iterable

我们也可使用isinstance来判断是否是可迭代对象。

生成器都是迭代器Iterator,而list等不是迭代器。有什么区别呢,最主要的区别是,容量。可以这样理解,list等是有大小的。而生成器是没有大小的,一个无限流。比如生成一个无限的自然数序列。生成器需要next函数调用。迭代器也可以使用isinstance来判断。

函数式编程

高阶函数

变量指向函数

函数名也是变量

函数名也是变量,指向函数。一旦我们更改了变量的指向就会报错。

传入函数

变量可以指向函数,函数的参数也可以接收变量。函数的参数也可以接收变量指向的函数,这就是高级函数。(套娃)

map/reduce

map函数接受两个参数一个函数参数、一个Iterable。举个例子:

我们自定义一个函数f,目的是为了,输出一个值得平方。那为什么第一个print函数输出的结果是这个呢?因为map返回的结果是一个iterator,而iterator是一个惰性序列。需要一个list函数让它把整个序列都计算出来并返回一个list。

map作为高级函数,事实上他把运算规则抽象化了。

reduce函数就是,将一个函数作用在一个序列上,而这个函数必须接受两个参数。

reduce函数就是将每一个元素和下一个元素做一个函数运算。

好像没太大用处。

但是结合一下。map函数就有意思了。

有意思吧。理解一下。假设python没有提供int函数,这样str也可以转换为int

filter

filter函数和map函数相似。接受一个函数和一个序列。不同的是,filter函数会根据返回的值,true还是false来判断是否保留值。

这个函数是判断序列是否是偶数,filter和map一样返回的值是一个Iteraltor,需要list函数获得结果并返回结果

strip函数,会去掉空字符串和特殊字符串(制表符或者换行符)filter函数的实质就是筛选。

用filter求素数

sorted函数

很熟悉是吧。排序,sorted函数

sorted函数还可以添加一个关键字key

添加关键字后,按照绝对值大小排列。

key值也可以是函数,比如上述函数,相当于先转换为负数在排序。sorted函数类似于映射函数,字符串也可以排序根据ascii码排列。

返回函数

高级函数可以接受函数作为参数,还可以将函数作为返回值。

还是套娃,我们可以看到相当于在函数里面再次建立了一个函数。当我们调用外层函数的时候,不会给我们求和值。我们需要现将内层的函数赋值给新的变量,然后再次调用函数。就得出了,求和结果。

每一次函数调用都会产生新的函数地址

闭包

为什么呢?

!!!注意:闭包并非立即执行。按照我们常规的思维来说,i,传入会立即返回一个值,但是,闭包不会。他会把循环都执行完,最后返回,如上图i最后等于3在返回(我们可以debug一下)。那怎么避免呢,闭包尽量不要是用循环。

如果必须滴使用循环呢?

在f函数中在嵌套一个函数。

问题,count函数return的是什么?函数。没错list接收到的是return的g函数。他和上面的count函数有什么区别呢?对参数,前者函数不会立即生效,会等到最后,返回。而后者就一个参数。

nonlocal

这两段代码比较一下,问什么后者会报错呢?

局部变量和公共变量的问题。内部函数调用外部函数变量时是没有问题的。但是只能读去,但是不能赋值。问什么呢?因如果赋值的话内部函数会认为这个变量是局部变量。而内部函数检测到内内部函数并没有该变量的定义就会报错。那该怎么办呢?

这样就好了。找找那不一样?对滴,内部函数里的x,我们已经定义了nonlocal不是局部变量。给解释器打好招呼了。所以就不会报错了。

匿名函数lambda

lambda函数和后者的效果是一样的。但是lambda函数,可以有效的避免函数名的冲突。但是lambda函数只能有一个表达式。

装饰器(decorate)

我们自定义了一个函数,目的显而易见,就是为了打印hello,但是我们想增加点别的功能但是又不想更改原函数,怎么办呢?这时候就要用到装饰器了。

有点难懂是吧。不急我们先分析一下。这个类似于f=log(f),我们知道,log函数返回的是一个函数,f是个变量指向了wrapper函数。调用f函数的时候f又指向了他自己。完美的闭环。

那如果decorate需要转入参数呢

三层嵌套,更难懂了。这个也相当于 f=decoretor(“text”)(f)。text参数传入,decoretor函数返回一个decorator函数,接下来和上面的操作一样的。

再次输出f函数的name属性,发现,为什么变为wrapper了,不是f吗?因为wrapper函数返回的就是“wrapper”,所以就改变了。那怎么办呢?我们可以导入functools模块就可以了。

偏函数

偏函数就是,使用functools模块,将一些函数的属性固定住(设置为默认值)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值