函数
查看自带的函数
查看命令:cmd下输入python,输入dir(__builtins__),可输出自带的函数
再用help查看函数如何使用。
函数的规则
没有return 值时会返回None
练习:找出一个序列中第二大的数
方法一: 先排序,输出第二个
#conding=utf-8
def secondBiggest(a):
a.sort()
return a[-2]
lista=[100,101,230,10,1]
print secondBiggest(lista)
方法二:先找到最大的删除,再输出最大就是第二大
#conding=utf-8
def secondBiggest(a):
max_number=max(a)
a.remove(max_number)
return max(a)
lista=[100,101,230,10,1]
print secondBiggest(lista)
方法三:
算法:
1 比较列表中前2个数,大的作为为列表中暂时的最大数,小的
作为次大数,分别存在2个变量里
2 遍历列表从第三个数开始以后后的值,去和最大值去比较,存在2种可能
3 如果大于,当前值作为列表中暂时的最大数,以前最大的变为
次大的。
4 如果小于,和次大的比较,大于它就是次大值,小于继续遍历
后续值。
#coding=utf-8
a=[10,10,10,0,10,10,0]
def secondBiggestNumber(lista):
#判断是否是列表或元组
if not isinstance(lista,(list,tuple)):
return None
#判断是否有2个以上元素
if len(lista)<=1:
return None
#判断每个元素的的值是否为数字
for i in lista:
if isinstance(i,(int,float)):
continue
else:
return None
#比较列表中前2个数,大的作为为列表中暂时的最大数,小的
#作为次大数,分别存在2个变量里
if lista[0]>lista[1]:
biggest_number=lista[0]
second_biggest_number=lista[1]
else:
biggest_number=lista[1]
second_biggest_number=lista[0]
#遍历列表从第三个数开始以后后的值,去和最大值去比较
for i in lista[2:]:
#如果大于,当前值作为列表中暂时的最大数,以前最大的变为
#次大的。
if i > biggest_number:
second_biggest_number=biggest_number
biggest_number=i
#如果小于,和次大的比较,大于它就是次大值,小于继续遍历
#后续值。
elif i == biggest_number:
continue
else:
if biggest_number==second_biggest_number:
second_biggest_number=i
if i >second_biggest_number:
second_biggest_number=i
return second_biggest_number
print secondBiggestNumber(a)
自己写的:
#conding=utf-8
def secondBiggest(lista):
firbig=lista[0]
secbig=lista[1]
if(firbig
firbig=lista[1]
secbig=lista[0]
for i in lista[2:]:
if(firbig
secbig=firbig
firbig=i
elif(firbig==i):
continue
else:
if i>secbig:
secbig=i
else:
continue
return secbig
lista=[100,101,230,10,1,300]
print secondBiggest(lista)
函数文档字符串
#conding=utf-8
def secondBiggest(lista):
u”’此函数用于找到次大值”’
firbig=lista[0]
secbig=lista[1]
if(firbig
firbig=lista[1]
secbig=lista[0]
for i in lista[2:]:
if(firbig
secbig=firbig
firbig=i
elif(firbig==i):
continue
else:
if i>secbig:
secbig=i
else:
continue
return secbig
lista=[100,101,230,10,1,300]
print secondBiggest(lista)
#print secondBiggest.__doc__
help(secondBiggest)
练习:写一个函数,这个函数要计算浮点数乘法的一万次相乘后的时间耗时
#conding=utf-8
import time
import random
def compute_float_time():
start_time=time.time()
#time.time是时间戳距离1970年的秒数,并不是获取当前时间
for i in range(10000):
random.random()**2
end_time=time.time()#再来一个时间戳
return end_time-start_time#计算差值
print compute_float_time()
无参函数
无参的函数无返回值,打印时会给出none
有参函数
形参分类: 必备参数,命名参数,缺省参数,不定长参数
>>> a=100
>>> def add_one(x):
… a=x+1
… return a
…
>>> add_one(a)
101
>>> a
100
>>> add_one()
Traceback (most recent call last):
File “”, line 1, in
TypeError: add_one() takes exactly 1 argument (0 given)
>>> add_one(1,2)
Traceback (most recent call last):
File “”, line 1, in
TypeError: add_one() takes exactly 1 argument (2 given)
局部变量和全局变量:
>>> a=100
>>> def add_one(x):
… global a
… a=a+1
…
>>> print a
100
>>> add_one(a)
>>> print a
101
>>> print a
101
函数外部定义的是全局变量,函数内部定义全局变量需要加global,不加时是局部变量
>>> a=100
>>> def add_one(x):
… a=a+1
…
>>> print a
100
>>> add_one(a)
Traceback (most recent call last):
File “”, line 1, in
File “”, line 2, in add_one
UnboundLocalError: local variable ‘a’ referenced before assignment
全局变量赋值后,在函数内调用是不会改变其初始赋值的,因为指向的id其实并不是同一个
>>> a=200
>>> id(a)
30315656L
>>> def f(x):
… a=2
… print id(a)
…
>>> f(a)
30310448
同时用会出错,只要在函数中操作全局变量并试图改变初始值,一定会报错。
解决办法:如果有加global
>>> a=[1]
>>> def add_one(x):
… a=a+1
…
>>> add_one(a)
Traceback (most recent call last):
File “”, line 1, in
File “”, line 2, in add_one
UnboundLocalError: local variable ‘a’ referenced before assignment
解决办法:如果有加global
>>> a=100
>>> def add_one(x):
… global a
… a=a+1
…
>>> id(a)
30312080L
>>> add_one(a)
>>> id(a)
30312056L
总结:
1 函数中使用全局变量,声明为global
2 否则当局部变量使用,且局部变量都要在函数开始的地方做赋值
3 如果函数中的变量没有声明为global,且在外部有同名的变量则可以当做全局变量直接使用
4一旦进行了赋值操作,则此变量变为局部变量且在使用前必须初始化赋值。
传可变对象—>默认参数必须指向不变对象!
#coding=utf-8
def add_end(L=[]):
L.append(‘END’)
return L
print add_end([1, 2, 3]) #调用正常
print add_end([‘x’, ‘y’, ‘z’]) #调用正常
print add_end()#调用正常
print add_end()#调用不正常
print add_end()#调用不正常
L=[]不是赋值语句,第一次使用的默认,后面每次调用都是同一个list的内存,出现调用不正常。
修正:
#coding=utf-8
def add_end(L=None):
if L is None:
L=[]
L.append(‘END’)
return L
print add_end([1, 2, 3]) #调用正常
print add_end([‘x’, ‘y’, ‘z’]) #调用正常
print add_end()#调用正常
print add_end()#调用不正常
print add_end()#调用不正常
总结:函数的默认参数最好别用可变对象,否则存在累加操作结果的情况
函数调用时需检查参数类型
写一个函数,统计一个字符串的字母个数,大小写均要统计。要求,尽可能写的健壮。
#coding=utf-8
def sum(str):
sum=0
for i in str:
if(i>=’a’ and i<=’z’):
sum+=1
elif(i>=’A’ and i<=’Z’):
sum+=1
return sum
str=raw_input(“Please input a str:”)
print sum(str)
老师:
_#encoding=utf-8
s=raw_input(“please input a string:”)
def count_string(s):
letter_count=0
if not isinstance(s,(str,unicode)):
return 0
for i in s:
if (i >=’a’ and i<=”z”) or (i >=’A’ and i<=”Z”):
letter_count+=1
return letter_count
print count_string(s)
拓展:String包
>>> import string
>>> string.uppercase
‘ABCDEFGHIJKLMNOPQRSTUVWXYZ’
>>> string.printable
‘0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!”#$%&\'()*+,-./:
;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c’
9.命名参数
#coding=utf-8
def sum(a,b,c):
return a*100+b*10+c
print sum(3,c=1,b=2)
命名的参数必须都放在后面,要不都别用,要么都用。
缺省参数
# -*- coding: utf-8 -*-
def say(message, times = 1):
print message * times
say(‘gloryroad!’)
say(u’万岁!’, 3)
缺省值不能放在最后面。
# -*- coding: utf-8 -*-
def say( times = 1,message):
print message * times
say(‘gloryroad!’)
say(u’万岁!’, 3)
类型判断
>>> def f():
… return 1,2,3,4,[5,6]
…
>>> print type(f())
>>> f()
(1, 2, 3, 4, [5, 6])
>>> a,b,c,d,e=f()
用元组作为函数的参数—>练习:累乘计算
>>> def mul(*arg):
… result=1
… for i in arg:
… if not isinstance(i,(int,float,long)):
… return None
… else:
… result*=i
… return result
…
>>> mul(1,2,3,4)
24
用字典作为函数的参数
>>> def mul(**kw):
… print type(kw)
… print kw
…
>>> mul(a=1,b=2,c=3)
{‘a’: 1, ‘c’: 3, ‘b’: 2}
练习:写一个连乘的函数,需要函数参数用**kw方式实现
# -*- coding: utf-8 -*-
def multil(**args):
mul=1
for i in args.values():
mul=mul*i
return mul
print multil(a=1,b=2,c=3,d=4)
总结:#*args和**args:都可以接受可变长度的参数个数区别:➢*args表示的是一个元组➢**args表示的是一个字典
组合使用
练习:mul(1,2,3,4,5,a=6,b=7)实现连乘函数,需要用到*arg,**kw,且函数有固定2个参数,a,b
# -*- coding: utf-8 -*-
def mul(a,b,*arg,**kw):
mul=a*b
for i in arg:
mul=mul*i
for j in kw.values():
mul=mul*j
return mul
print mul(1,2,3,4,5,a=6,b=7)
报错:
a和b被重复使用了
# -*- coding: utf-8 -*-
def mul(a,b,*arg,**kw):
mul=a*b
for i in arg:
mul=mul*i
for j in kw.values():
mul=mul*j
return mul
print mul(1,2,3,4,5,x=6,y=7)
老师:
>>> def mul(a,b,c=10,*arg,**kw):
… result=1
… result=result*a*b*c
… for i in arg:
… result*=i
… for i in kw.values():
… result*=i
… return result
…
>>> print mul(1)
Traceback (most recent call last):
File “”, line 1, in
TypeError: mul() takes at least 2 arguments (1 given)
>>> print mul(1,2)
20
>>> print mul(1,2,3)
6
>>> print mul(1,2,3,4)
24
>>> print mul(1,2,3,4,5)
120
>>> print mul(1,2,3,4,5,a=6,b=7)
Traceback (most recent call last):
File “”, line 1, in
TypeError: mul() got multiple values for keyword argument ‘a’
>>> print mul(1,2,3,4,5,x=6,y=7)
5040
lambda函数
➢lambda语句被用来创建新的函数对象,并且在运行时返回它们。
➢Python使用lambda关键字来创建匿名函数。这种函数得名于省略了用
def声明函数的标准步骤。
➢lambda只是一个表达式,函数体比def简单很多
➢lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表
达式中封装有限的逻辑进去。
➢lambda函数拥有自己的名字空间,且不能访问自由参数列表之外全局名
字空间里的参数。
➢虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,
后者的目的是调用小函数时不占用栈内存从而增加运行效率。
➢lambda会返回一个函数对象,但这个对象不会赋给一个标识符,而def
则会把函数对象赋值给一个变量(函数名)。
➢像if或for或print等语句不能用于lambda中。
练习:计算x的y次方
>>> g=lambda x,y:x**y
>>> print g(2,3)
8
16.Lamda可做函数并return一个值
#encoding=utf-8
def make_repeater(n):
return lambda s: s*n
twice = make_repeater(2)#等价lambda s: s*2
print twice(‘word’)##等价lambda s: ‘word’*2
print twice(5)###等价lambda s: 5*2
repr函数用来取得对象的规范字符串表示。反引号(也称转换符)可以完成相同的功能。注意,在大多数时候有eval(repr(object)) == object。
>>> class a:
… def __str__(self):
… return “hello”
… def __repr__(self):
… return “gloryroad”
…
>>> x=a()
>>> x
gloryroad
>>> print x
hello
>>> class a:
… def ___str__(self):多敲了一个下划线
… return “hello”
… def __repr__(self):
… return “glo”
…
>>> x=a()
>>> x
glo
>>> print x
glo
>>> repr(x)
‘glo’
map函数
>>> map(str,[1,2,3,4])
[‘1’, ‘2’, ‘3’, ‘4’]
>>> def add(x):
… return x+1
…
>>> map(add,[1,2,3])
[2, 3, 4]
练习:lista=[1,2,3,4]计算这四个数的平方
>>> def mul(x):
… return x**2
…
>>> map(mul,[1,2,3,4])
[1, 4, 9, 16]
老师:
>>> map(lambda x:x**2,[1,2,3,4])
[1, 4, 9, 16]
拓展:lambda可以同时传入两个序列
>>> map(lambda x,y:x+y,[1,2,3,4],[10,20,30,40])
[11, 22, 33, 44]
若对应的参数传递的不一致,会报错。
>>> map(lambda x,y:x+y,[1,2,3,4],[10,20,30])
Traceback (most recent call last):
File “”, line 1, in
File “”, line 1, in
TypeError: unsupported operand type(s) for +: ‘int’ and ‘NoneType’
filter()函数可以对序列做过滤处理
例子一:
>>> filter(lambda x:x>2,[-1,0,1,2,3,4])
[3, 4]
例子二:
#encoding=utf-8
def guolvhanshu(num):
if num>5 and num<10:
return num
#定义一个序列
seq=(12,50,8,17,65,14,9,6,14,5)
#使用filter函数
result=filter(guolvhanshu,seq)
#(8,9,6)
print result
reduce用来将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给reduce中的函数func()(必须是一个二元操作函数)先对集合中的第1,2个数据进行操作,得到的结果再与第三个数据用func()函数运算,最后得到一个结果。
一步一步累加或累乘
>>> reduce(lambda x,y:x+y,[1,2,3,4,5])
15
>>> 1+2=3 3+3=6 6+4=10 10+5=15
>>> reduce(lambda x,y:x*y,[1,2,3,4,0])
0
>>> reduce(lambda x,y:x*y,[1,2,3,4])
24
>>> reduce(lambda x,y:x+y,[1,2,3,4],100)
110
>>> 100(x)+1(y)=101 101(x)+2(y)=103 103(x)+3(y)=106 106(x)+4(y)=110
exec语句用来执行存储在字符串或文本中有效的Python语句
>>> eval(“a+1”)
2
>>> print eval(“a+1”)
2
>>> exec(‘”abc”*2’)
>>> exec(‘print “abc”*2’)
abcabc
>>> eval(‘”abc”*2’)
‘abcabc’
>>> a=1
>>> exec(“a+1”)
>>> exec(‘print a+1’)
2
ange会直接生成一个list对象xrange则不会直接生成一个list,而是每次调用返回其中的一个值【xrange返回的是一个生成器】
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> xrange(10)
xrange(10)
xrange省内存
函数的引用
计算函数耗时:
>>> def f():
… for i in xrange(100000000):
… i+1
…
>>> def time_consume(f):
… s1=time.time()
… f()
… return time.time()-s1
…