前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python快速学习第五天

Python快速学习第五天

作者头像
汤高
发布2018-01-11 15:48:19
6680
发布2018-01-11 15:48:19
举报
文章被收录于专栏:积累沉淀

第五天:抽象

1、    函数

检测函数是否可调用:callable

>>> import math

>>> y=math.sqrt

>>> callable(y)

True

>>> x=1

>>> callable(x)

False

   注意:Python3.0不在支持callable,需要使用表达式hasattr(func,_call_call_)代替

   创建函数:def functionname(params):

>>>def fibs(num):

...     'Get fibonaqi sequnce! '

...     result=[0,1]

...     for i in range(num-2):

...            result.append(result[-2]+result[-1])

...     return result

...

>>>fibs(10)

[0, 1,1, 2, 3, 5, 8, 13, 21, 34]

用于def后面的'Getfibonaqi sequnce! '添加文档字符串,相当于注释#,使用help()可以查询函数的文档字符串

help(fibs)

Help on function fibs in module __main__:

fibs(num)

    Getfibonaqi sequnce!

...skipping...

Help on function fibs in module __main__:

fibs(num)

    Getfibonaqi sequnce!

 return后不加值,只表示函数的结束,而没有返回值,这样可以避免应该返回序列时,意外返回None

>>> def test():

...     print 'tanggao'

...     return

...     print 'tanggao isgood'

...

>>> x=test()

tanggao

>>> print x

None

2、   参数对外部变量影响

   函数内给参数赋值,不会改变外部变量的值,参数存储在局部作用域中

>>> def try_to_change(n):

...     n=3

...

>>> t=4

>>> try_to_change(t)#虽然在函数内部重新赋值,但外部不变

>>> t

4

但是对于可改变的数据结构,如列表,参数的内部赋值会改变外部变量的值

   内部参数与外部变量指向同一个列表,所以会被修改

   若不想改变外部列表,可以传进一个副本

>>> def change(n):

...    n[0]='tanggao'

...

>>> names=['hello','world']

>>> change(names)

>>> names

['tanggao', 'world']

>>>  #采用普通方法进行模拟 

...

>>> names=['hello','world']

>>> n=names

>>> n[0]='tanggao'

>>> names

['tanggao', 'world']

完整示例——存储名字,并能用名字、中间名或姓来查找联系人

   若名字为'MagusLie Hetland'存储格式类似

   data = {

           'first':{ 'Magus': 'Magus Lie Hetland'},

           'middle':{'Lie': 'Magus Lie Hetland'},

           'last':{'Hetland': 'Magus Lie Hetland'}

       }

   注意insert(index,value)函数,在列表的索引位置插入值

Python代码  

1.  >>> def init(data):  #data作为存储表,初始化

2.      data['first'] = {}  

3.      data['middle'] = {}  

4.      data['last'] = {}  

5. 

6.  >>> def store(data, full_name): #存储,将全名存储到表中

7.      names = full_name.split()  #将名字按空格(即first,middle,last)分开,返回列表,如'Ma Li He'返回['Ma', 'Li', 'He']  

8.  if len(names) == 2: names.insert(1, '')#若无中间名,则插入空来表示中间名['Mr', 'Zha']返回['Mr', '', 'Zha']  

9.      labels = 'first', 'middle', 'last' #元组

10. for label, name in zip(labels, names):  #元组与序列间也可使用zip

11.         people = lookup(data, label, name)  

12. if people:  

13.             people.append(full_name)  

14. else:  

15.             data[label][name] = [full_name] #当键不存在时,自动添加键值对,

16. #但如果输出不存在键对应值,则报错

17.

18. >>> def lookup(data, label, name): #查找,根据label查找是name的中间人  

19. return data[label].get(name)  

20.

21.

22. >>> MyNames = {}  

23. >>> init(MyNames)  

24. >>> store(MyNames, 'Magnus Lie Hetland')  

25. >>> lookup(MyNames, 'middle', 'Lie')  

26. ['Magnus Lie Hetland']  

27. >>> store(MyNames, 'Robin Hood')  

28. >>> store(MyNames, 'Robin Locksley')  

29. >>> lookup(MyNames, 'first', 'Robin')  

30. ['Robin Hood', 'Robin Locksley']  

31. >>> store(MyNames, 'Mr. Gumby')  

32. >>> lookup(MyNames, 'middle', '')  

33. ['Robin Hood', 'Robin Locksley', 'Mr. Gumby']  

   例2. 不可变的数字和可改变的参数

Python代码  

1.  >>> def inc(x): return x + 1  

2. 

3.  >>> foo = 10  

4.  >>> inc(foo)  

5.  11  

6.  >>> foo #外部变量未发生变化

7.  10  

8.  >>> foo = inc(foo) #将foo重新赋值  

9.  >>> foo  

10. 11  

   使用列表外部变量foo改变了

Python代码  

1.  >>> def inc(x): x[0] = x[0] + 1  

2. 

3.  >>> foo = [10]  

4.  >>> inc(foo)  

5.  >>> foo  

6.  [11]  

3. 关键字参数和默认值

   位置:是指根据参数的对应位置传参,如def a(a,b,c):,调用a(1,2,3),1传给a,2传给b,3传给c,这样参数位置容易记混。

   关键字参数,适用于大规模程序,清晰

Python代码  

1.  >>> def hello(name, greeting):  

2.  print '%s, %s!' %(greeting, name)  

3. 

4. 

5.  >>> hello('sun', 'Hello')  #位置参数

6.  Hello, sun!  

7.  >>> hello(name = 'Sun', greeting = 'Hello')  #关键字参数

8.  Hello, Sun!  

9.  >>> hello(greeting = 'Hello', name = 'Sun') #关键字参数,不必关心位置

10. Hello, Sun!  

   默认值

Python代码  

1.  >>> def hello(name = 'world', greeting = 'Hello'):  

2.  print '%s, %s!' %(greeting, name)  

3. 

4. 

5.  >>> hello()  

6.  Hello, world!  

7.  >>> hello('Sun')  

8.  Hello, Sun!  

9.  >>> hello(greeting = 'Hi')  

10. Hi, world!  

   位置参数与关键字参数混用,将位置参数放在前面。尽量避免这么用,容易引起混乱。

Python代码  

1.  >>> def hello(name, greeting = 'Hello', punc = '!'):  

2.  print '%s, %s%s' %(greeting, name, punc)  

3. 

4. 

5.  >>> hello('Sun')  

6.  Hello, Sun!  

7.  >>> hello('Sun', 'Hi')  

8.  Hi, Sun!  

9.  >>> hello('Sun', punc = '..')  

10. Hello, Sun..  

11. >>> hello()   #因为name是必须要有,若有默认值,则可没有  

12.

13. Traceback (most recent call last):  

14.   File "<pyshell#385>", line 1, in <module>  

15.     hello()  

16. TypeError: hello() takes at least 1 argument (0 given)  

17. >>>   

4. 收集参数——在定义时使用*或**,用来收集参数,允许使用不定数量的参数

   *:收集其余的位置参数并作为元组 返回

Python代码  

1.  >>> def print_params2(title, *params):  

2.  print title  

3.  print params  

4. 

5. 

6.  >>> print_params2('Param:', 1, 2, 3)  

7.  Param:  

8.  (1, 2, 3)  #以元组形式返回

9.  >>> print_params2('Param:') #不提供收集元素时,返回空元组

10. Param:  

11. ()  

12. >>> print_params2('Param:', 1)   

13. Param:  

14. (1,) #只有一个元素时,仍为元组

   **:收集其余的关键字参数并作为字典 返回,可与其他混用

Python代码  

1.  >>> def print_params3(x, y, z = 3, *pospar, **keypar):  

2.  print x, y, z  

3.  print pospar  

4.  print keypar  

5. 

6. 

7.  >>> print_params3(1,2,3,4,5,6,7, fool = 1, bar = 2)  

8.  1 2 3  

9.  (4, 5, 6, 7)  

10. {'fool': 1, 'bar': 2}  

11. >>> print_params3(1,2)  

12. 1 2 3  

13. ()  

14. {}  

5. 收集参数的翻转过程——在调用时使用*或**,将参数分配到定义的参数中,用于字典或列表分割时

   用于列表

Python代码  

1.  >>> def add(x,y): return x + y  

2. 

3.  >>> params = (1,2)  

4.  >>> add(*params)  

5.  3  

   用于字典

Python代码  

1.  >>> def hello(name, greeting):  

2.  print '%s, %s!' %(greeting, name)  

3. 

4. 

5.  >>> params = {'name': 'Sir Robin', 'greeting': 'Welcome'}  

6.  >>> hello(**params)  

7.  Welcome, Sir Robin!  

8. 

9. 

   参数使用实例

Python代码  

1.  #模拟步长大于0的range()  

2.  >>> interval(10)  

3.  start = 0 stop = 10 step =  1  

4.  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]  

5.  >>> def interval(start, stop=None, step=1):  

6.  'Imitates range() for step > 0'

7.  if stop is None: #若未给stop指定值  

8.          start, stop = 0, start #多个赋值,0赋值给start,start的值赋值给stop  

9.      result = []  

10.     i = start  

11. while i < stop:  

12.         result.append(i)  

13.         i += step  

14. return result  

15.

16. #

17. >>> def story(**kwds):  

18. return '%(job)s called %(name)s.' %kwds  

19.

20. >>> def power(x, y ,*others):  

21. if others:  

22. print 'Received redundant parameters:',others  

23. return pow(x,y)  

24.

25. #使用

26. >>> params = {'job':'language','name':'python'}  

27. >>> print story(**params) #调用时分割字典,定义中收集

28. language called python.  

29. >>> del params['job']  

30. >>> print story(job='test', **params)  

31.

32. >>> power(2,3,'test')  

33. Received redundant parameters: test  

34.

35. >>> params = (5,) * 2 #即(5,5)

36. >>> power(*params) #先分割,在赋给x,y  

37. 3125  

6.作用域

   x = 1, 将名字x引用到值1上,类似字典

   内建函数vars()返回这个字典

Python代码  

1.  >>> x = 1  

2.  >>> scope = vars()  

3.  >>> scope['x']  

4.  1  

5.  >>> scope['x'] += 1 #一般情况下,vars()返回的字典不能修改  

6.  >>> x  

7.  2  

   局部变量,全局变量

   函数内部访问全局变量,慎用!

Python代码  

1.  >>> def com(para): print para + external  

2. 

3.  >>> external = 'external'

4.  >>> com('param ')  

5.  param external  

   若全局变量与局部变量名字相同,会被局部变量覆盖,可使用global()类似vars(),获得全局变量的字典

Python代码  

1.  >>> def com(para): print para + globals()['para']  

2. 

3.  >>> para = 'berry'

4.  >>> com('test ')  

5.  test berry  

   重绑定全局变量,将变量引用到其他新值——函数内部声明全局变量

Python代码  

1.  >>> x = 1  

2.  >>> def change_global():  

3.  global x  

4.      x = x + 1  

5. 

6. 

7.  >>> change_global()  

8.  >>> x  

9.  2  

   嵌套作用域——函数中定义函数,例如闭包

   外部作用域中的变量一般不能被改变,但是用闭包,每次调用外层函数,内部函数都会被重新绑定,也即外部作用域factor每次都有一个新值

Python代码  

1.  >>> def multiplier(factor):  

2.  def multiplyByFactor(number):  

3.  return number * factor  

4.  return multiplyByFactor  #返回一个函数,这时并未调用

5. 

6.  >>> double = multiplier(2)  #double是一个函数

7.  >>> double   #double是一个函数

8.  <function multiplyByFactor at 0x0214C6F0>  

9.  >>> double(5)  #调用multiplyByFactor(number)

10. 10  

11. >>> multiplier(2)(5) #效果同上

12. 10  

   7. 递归——每调用一个函数,都会创建一个新的命名空间,意味着当函数调用自身时,实际上调用的是两个不同的函数

    阶乘

Python代码  

1.  >>> def factorial(n):  

2.  if n == 1:  

3.  return 1  

4.  else:  

5.  return n * factorial(n-1)  

6. 

7.  >>> factorial(5)  

8.  120  

    幂

Python代码  

1.  >>> def power(x, n):  

2.  if n == 0:  

3.  return 1  

4.  else:  

5.  return x * power(x, n - 1)  

6. 

7. 

8.  >>> power(2,3)  

9.  8  

   递归实例——二元搜索

   前提:排好序

   若上下限相同,则那就是数字所在位置,返回;

   否则,找到两者的中间,查找数字是在左侧还是右侧,继续查找数字所在的那半部分。

Python代码  

1.  >>> def search(sequence, number, lower = 0, upper = None):  

2.  if upper is None: upper = len(sequence) - 1  

3.  if lower == upper:  

4.  assert number == sequence[upper]  

5.  return upper  

6.  else:  

7.          middle = (lower + upper) // 2  

8.  if number > sequence[middle]:  

9.  return search(sequence, number, middle + 1, upper)  

10. else:  

11. return search(sequence, number, lower, middle)  

12.

13.

14. >>> seq = [34, 67, 8, 123, 4, 100, 95]  

15. >>> seq.sort()  

16. >>> seq  

17. [4, 8, 34, 67, 95, 100, 123]  

18. >>> search(seq, 34)  

19. 2  

总结:

元组输出格式化,直接使用键,而不需要加引号

Python代码  

1.  >>> d = {'a':1, 'b':2}  

2.  >>> print '%(a)s corresponds to %(b)s.' %d #注意a有括号,无引号  

3.  1 corresponds to 2.  

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-08-14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档