将语句组合成函数,可以告诉计算机如何完成任务,且只需说一次,而不用反复向计算机传达详细指令。
斐波那契数(一种数列,其中每个数都是前两个数的和):
>>> fibs = [0,1] >>> for i in range(10): fibs.append(fibs[-2]+fibs[-1]) >>> fibs [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
优化一下代码,使其指定动态的范围:
>>> fibs = [0,1] >>> num = input('enter:') enter:10 >>> for i in range(int(num)-2): fibs.append(fibs[-2]+fibs[-1]) >>> fibs [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
如果不从用户那里读取数字,而是通过参数来获取,可以继续优化代码:
>>> def fibs(num): re = [0,1] for i in range(num-2): re.append(re[-2]+re[-1]) return re >>> fibs(10) [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
def语句定义函数,return语句用于从函数返回值。num是一个形参,可以在其他地方多次调用fibs(),而不用每次都要将代码再敲一遍。
除了#注释之外,还有一种编写注释的方式,就是添加独立的字符串。放在函数开头的字符串称为文档字符串。
>>> def square(x): 'Calculates the square of the number x.' return x * x >>> square.__doc__ #访问文档字符串 'Calculates the square of the number x.'
__doc__是函数的属性。
>>> help(square) #内置函数help可以获取有关函数的信息 Help on function square in module __main__: square(x) Calculates the square of the number x.
修改参数
当参数为可变的数据结构(列表)时,在函数内修改参数,在外面调用函数。
>>> def change(n): n[0] = 'Mr.Gumby' >>> names = ['Mrs.Entity','Mrs.Thing'] >>> change(names) >>> names ['Mr.Gumby', 'Mrs.Thing']
上面栗子也可以这么写:
>>> names = ['Mrs.Entity','Mrs.Thing'] >>> n = names #假装传递名字作为参数 >>> n[0] = 'Mr.Gumby' #修改列表,这步上面是在函数内进行的 >>> names ['Mr.Gumby', 'Mrs.Thing']
将同一个列表赋给两个变量时,这两个变量将同时指向这个列表。想避免这种结果,必须创建列表的副本。
>>> names = ['Mrs.Entity','Mrs.Thing'] >>> n = names[:] #对序列进行切片操作时,返回的切片是副本。现在n和names包含2个相等但不同的列表。这里也可以用names.copy()来创建副本。 >>> n[0] = 'Mr.Gumby' >>> names ['Mrs.Entity', 'Mrs.Thing'] >>> n ['Mr.Gumby', 'Mrs.Thing']
将切片参数传给函数,也不会影响:
>>> def change(n): n[0] = 'Mr.Gumby' >>> names = ['Mrs.Entity','Mrs.Thing'] >>> change(names[:]) >>> names ['Mrs.Entity', 'Mrs.Thing']
栗子:假设编写一个程序,让它储存姓名,并让用户能够根据名字,中间名或姓找人。
创建初始化数据结构的函数:
>>> def init(data): data['first'] = {} data['middle'] = {} data['last'] = {} >>> storage = {} >>> init(storage) #这个函数承担了初始化职责,提高了代码的可读性。 >>> storage {'first': {}, 'middle': {}, 'last': {}}
然后需要一个函数来获取人员姓名:
>>> def lookup(data,label,name): return data[label].get(name)
接着要将人员存储到数据结构中:
>>> def store(data,full_name): #将参数data和full_name提供给这个函数。 names = full_name.split() #通过拆分full_name创建1个名为names的列表。 if len(names) == 2 : names.insert(1,'') #如果只有名字和姓,没有中间名,就将中间名设为空字符串 labels = 'first','middle','last' #将label存储到元组中(也可以是列表) for name,label in zip(names,labels): #zip函数将label和name合并,可以对label-name对执行一些操作 people = lookup(data,label,name) if people: people.append(full_name) #将full_name插入一个新列表 else: data[label][name]=[full_name]
现在运行看看:
>>> me = {} >>> init(me) >>> me {'first': {}, 'middle': {}, 'last': {}} >>> store(me,'Magnus Lie Hetland') >>> me {'first': {'Magnus': ['Magnus Lie Hetland']}, 'middle': {'Lie': ['Magnus Lie Hetland']}, 'last': {'Hetland': ['Magnus Lie Hetland']}} >>> lookup(me,'middle','Lie') ['Magnus Lie Hetland'] >>> store(me,'Robin Hood') >>> store(me,'Robin Locksley') >>> store(me,'Mr. Gumby') >>> lookup(me,'first','Robin') ['Robin Hood', 'Robin Locksley'] >>> lookup(me,'middle','') ['Robin Hood', 'Robin Locksley', 'Mr. Gumby']