python content函数 自定义_进阶第二课 Python内置函数(补)及自定义函数

内置函数(补)

1、float()

上一课中,我们可以使浮点数变为整数;相反的也可以把整数变为浮点数。看示例:

>>> a=10

>>> b=float(10)>>>b10.0

2、max()

在一系列数中取最大的一个。看示例:

>>> max(1,2,3,4,5)5

3、min()

在一系列数中取最小的一个。看示例:

>>> min(1,2,3,4,5)1

4、help()

查看说明。看示例:

>>> help(int)

大家自己试试看int的说明。

5、迭代器

上一课我们介绍了iter()这个内置函数。这里再详细介绍一下。

5.1 可以直接作用于for循环的对象统称为可迭代对象(Iterable)。

5.2 可以被next()函数调用并不断返回下一个值的对象称为迭代器(Iterator)。

5.3 所有的Iterable均可以通过内置函数iter()来转变为Iterator。

5.4 对迭代器来讲,有一个__next()就够了。在你使用for 和 in 语句时,程序就会自动调用即将被处理的对象的迭代器对象,然后使用它的next__()方法,直到监测到一个StopIteration异常。

>>> a=[1,2,3]>>> b=iter(a)>>>next(b)1

>>>next(b)2

>>>next(b)3

>>>next(b)

Traceback (most recent call last):

File"", line 1, in next(b)

StopIteration

a是一个列表,也就是可迭代对象。b是一个迭代器。

6、yield()

6.1 使用了yield的函数叫生成器,即生成器函数。还可以用生成器表达式来创建生成器:

>>> a=[x**2 for x in range(10)]>>>a

[0,1, 4, 9, 16, 25, 36, 49, 64, 81]>>> b=(x**2 for x in range(10))>>>b at 0x000001FDA3A7D780>

分析一下:a是一个列表,a所有的值都储存在计算机的内存中;b是一个生成器。

要想打印生成器中的内容,有2中方法:

1)next()

>>>g.next()

0>>>g.next()

1>>>g.next()

4>>>g.next()

9>>>g.next()

16>>>g.next()

25>>>g.next()

36>>>g.next()

49>>>g.next()

64>>>g.next()

81>>>g.next()

Traceback (most recent call last):

File"", line 1, in StopIteration

当b中的值调出完毕后,再执行next(),系统会报错。

2)for循环

>>> b=(x**2 for x in range(10))>>> for i inb:print(i,end=' ')

01 4 9 16 25 36 49 64 81

>>> for i in b:

print(i,end=' ')

>>>

这里可以看到b作为一个生成器,完成一个循环后就无法再次使用。

6.2 生成器函数

生成器也是一个函数,返回一个迭代器。简单想生成器也是一个迭代器。

在调用生成器时,一旦遇到 yield 函数会暂停并保存当前所有的运行信息(也就是函数内所有变量的状态会被保留,同时函数代码执行到的位置会被保留,感觉就像函数被暂停了一样),并返回 yield 的值,在下一次执行 next() 方法时从当前位置继续运行。

看示例:

>>> defpingfang_2(a):

b=1

while b<=a:yield b**2b=b+1

>>> for i in pingfang_2(5):print(i)1

4

9

16

25

分析一下:

1)函数pingfang_2中使用yield来返回一个值而非return返回值,所以这个函数是一个生成器,调用这个函数就会返回一个迭代器(即pingfang_2(5))。

2)生成器的好处是延迟计算,一次返回一个结果。也就是说,它不会一次生成所有的结果,这对于大数据量处理,将会非常有用。举个栗子-_-!!

sum(i for i in range(10000000000))

虽然range的范围很大,到10的10次方。但是由于使用的是(),所以i实在一个生成器中循环,每次生成器只返回一个数字:0,1,2,3...占用内存极小。

反例也有一个:

sum([i for i in range(10000000000)])

执行之前请先检查是否为64位操作系统,内容是否为16GB以上,否则你还没等看明白怎么回事你的电脑就死机啦。。。

因为使用的是[],意味着首先生成一个列表,从0到10的10次幂-1。列表越大占用内存越多,会显著降低电脑的运行速度甚至死机。每次也是取一个数。

另外,我碰到这样一个问题:

电脑配置:AMD1600,win10,使用节能模式,显示CPU主频1.32GHz,内存16GB@3000MHz。

此时我执行下列代码:

>>> deftime1():importtime

a=time.time()

sum([ifor i in range(10000000)])

b=time.time()return b-a>>>time1()1.9722506999969482

>>> deftime2():importtime

a=time.time()

sum(ifor i in range(10000000))

b=time.time()return b-a>>>time2()2.1406807899475098

生成器虽说节省内存,但是速度竟然比列表慢!!!

然后我把电源模式改为了“高性能”,再次执行上述2个函数:

>>>time1()0.8594393730163574

>>>time2()0.8438072204589844

这一次结果相反!!!生成器即节省内存,又节省时间。

同样是高性能下,把range增加10倍,看结果:

>>> deftime3():importtime

a=time.time()

sum([ifor i in range(100000000)])

b=time.time()return b-a>>> deftime4():importtime

a=time.time()

sum(ifor i in range(100000000))

b=time.time()return b-a>>>time3()8.884530067443848

>>>time4()8.421962976455688

时间差距不明显。内存消耗差距大。

内置函数先讲这些,今后碰到没讲的,随时补充。下面介绍下自定义函数。

自定义函数

介绍了这么多内置的函数,那我们可以自己编写函数吗?可以的,称之为自定义函数。无论是内置的函数,还是我们自定义的函数,都是可以重复使用的。

1、函数的格式:

>>> defadd_1(a,b):return(a+b)>>> add_1(10,15)25

看看格式:

1.1 def开头 ,空格后是自定义函数的函数名,这个函数名的命名不要与系统内置的函数名重复,且命名与变量一样开头字符可以是下划线或者英语字母,不能使数字开头。

1.2 函数名后面是括号,里面是参数,可以没有参数,看示例:

>>> def_print():print('I wanna learn Python.')>>>_print()

I wanna learn Python.

1.3 自定义函数内部,依然可以添加说明,与之前的用法一致;

1.4 注意缩进。

1.5 看下取值逻辑:

>>> defmianji(chang,kuan):

s=chang*kuanprint('长:',chang)print('宽:',kuan)print("面积是:")returns>>> mianji(20,50)

长:20宽:50面积是:1000

函数mianji中,定义了2个参数:chang和kuan。引用函数时,也提供了这2个参数对应的值。可以看到函数参数和调用时提供的参数,是有对应顺序的:chang对应的是20,kuan对应的是50。

1.6 因为函数mianji中定义了2个参数,调用时如果只传入一个,会怎么样呢?看示例:

>>> mianji(20)

Traceback (most recent call last):

File"", line 1, in mianji(20)

TypeError: mianji() missing1 required positional argument: 'kuan'

会报错!提示缺少一个参数值,这个参数值对应的参数是kuan。

1.7 再一个问题:调用自定义函数时,是否可以改变参数的顺序呢?看示例。

>>> mianji(kuan=50,chang=20)

长:20宽:50面积是:1000

答案是可以的。无非就是在调用自定义函数时,在括号中把函数的参数和值一并写入。

1.8 默认参数

>>> def person(name,age,salary=10000):print(name)print(age)print(salary)>>> person('zhaoyun',23)

zhaoyun23

10000

>>> person('zhaoyun',23,5000)

zhaoyun23

5000

>>> person(age=23,name='zhaoyun',8000)

SyntaxError: positional argument follows keyword argument>>> person(age=23,name='zhaoyun',salary=8000)

zhaoyun23

8000

在自定义函数person中有3个参数,其中salary给出了默认值10000。调用时,如果不提供salary这个参数的值,就会按默认值打印出来;如果给出新的值,就会打印新的值。

再就是如果通过参数名给出对应值,那么所有参数都要标出,否则会报错。

1.9 如果想自定义一个函数,且该函数的参数个数不固定,要如何处理呢?看示例:

>>> def buguding1(*args):print(args)>>> buguding1(1,2,3,45,5)

(1, 2, 3, 45, 5)>>> buguding1([1,2,4,43,5,7])

([1, 2, 4, 43, 5, 7],)

当参数个数不固定,可以使用*args作为参数。当然‘args’并不是一个固定的名称,说必须使用*args作为不固定参数,使用*a或者*_12a也可以。不过既然多数人都使用*args,那么你也这么用。

上面调用时,我们传入了元祖和列表,都可以正常打印。

还可以这么用:

>>> def buguding_2(a,*args):print(a)print(args)>>> buguding_2(1,2,3,4,5)1(2, 3, 4, 5)

参数有2部分,注意不是2个。第一部分是一个参数a,第二部分是一个不固定个数的参数*args。调用时,1赋值给了a,其余的2,3,4,5赋值给了args。

还可以这样使用:

>>> def buguding_2(a,*args,b):print(a)print(args)print(b)>>> buguding_2(1,2,3,4,5)

Traceback (most recent call last):

File"", line 1, in buguding_2(1,2,3,4,5)

TypeError: buguding_2() missing1 required keyword-only argument: 'b'

>>> buguding_2(1,2,3,4,b=5)1(2, 3, 4)5

有3部分参数,a、*args和b。调用时如果不指定b的值就会报错,以为*args包含了除第一个参数外所有值,b就没有传入值。指定b的值之后,就没问题了。

1.10 如果传入的参数是字典,就需要使用另一种方式:

>>> def buguding_3(**kwargs):print(kwargs)>>> buguding_3(name='zhaoyun',age=23,salary=10000)

{'name': 'zhaoyun', 'age': 23, 'salary': 10000}

如果传入值是字典类型且不固定长度,就可以使用**kwargs作为函数的参数。当然**a也可以。道理同上。

1.11 *args和**kwargs可以混用。看示例:

>>> def buguding_4(*args,**kwargs):print(args)print(kwargs)

这样一来,这个自定义函数就能打印传入的元祖、列表和字典。看示例:

>>> buguding_4(1,2,3,5,6)

(1, 2, 3, 5, 6)

{}

调用时只传入了一个元祖,并未传入字典,此时程序默认传入的是一个空字典。反之亦然。看示例:

>>> buguding_4(name='zhaoyun',age=23,height=200)

()

{'name': 'zhaoyun', 'age': 23, 'height': 200}

调用时如果只传入一个字典,那么程序默认你也传入了一个元祖,不过是空元组罢了。

>>> buguding_4(1,2,3,5,6,name='zhaoyun',age=23,height=200)

(1, 2, 3, 5, 6)

{'name': 'zhaoyun', 'age': 23, 'height': 200}

同时传入元祖和字典的结果。

>>> buguding_4(name='zhaoyun',age=23,height=200,1,2,3,5,6,)

SyntaxError: positional argument follows keyword argument

调用时如果颠倒参数顺序,结果就是报错。

1.12 不用定义的函数,称之为‘匿名函数’,格式也有所不同。看示例:

>>> a=lambda x,y:x+y>>> a(10,100)110

使用lambda定义一个函数,lambda后面是变量,用逗号隔开,然后是冒号,最后是变量的算法也就是返回值。调用时输入参数即可。

1.13 变量的作用域。

所谓变量的作用域,就是指变量的有效范围。先看示例:

>>> a=10

>>> b=2

>>> c=a**b>>>c100

上面这段程序中,c的值由a和b计算得来,说明在计算c的值过程中,a和b都起了作用。那么在这一过程,都是a和b的作用域。再看另一个例子:

>>> defpingfang(a):return a**2

>>> pingfang(10)100>>>a

Traceback (most recent call last):

File"", line 1, in a

NameError: name'a' is not defined

这段代码中,函数pingfang中有一个参数a,a也是一个变量。a这个变量的作用域就是函数pingfang内,一旦出了这个函数,a就不存在了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值