Python学习——02-Python基础——4-变量与递归函数

Posted c富-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python学习——02-Python基础——4-变量与递归函数相关的知识,希望对你有一定的参考价值。

6.局部变量和全局变量

在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。

全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。
当全局变量与局部变量同名时:
在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用。
  
  ##python中的def:def关键字用来定义函数

(1)全局变量

 1 name=\'lhf\'
 2 
 3 def change_name():          
 4     print(\'我的名字\',name)
 5 
 6 change_name()[这代表运行这个函数],必须要运行

输出:

我的名字 lhf

(2)局部变量

1 1 name=\'lhf\'
2 2 def change_name():
3 3     name=\'帅了一笔\'
4 4     print(\'我的名字\',name)
5 5 
6 6 change_name()
7 7 print(name)

输出:

我的名字 帅了一笔
帅了一笔

(3)用global name讲局部变量转换成全局变量

1 name=\'lhf\'
2 def change_name():
3     global name
4     name=\'帅了一笔\'
5     print(\'我的名字\',name)
6 
7 change_name()
8 print(name)

输出:

1 我的名字 帅了一笔
2 帅了一笔

 

 

请用自己的话解释全局变量与局部变量的区别,静态变量与自动变量的区别:

  全部变量就是在整个工程工都可以调用。比如我在一个标准模块中定义了一个全局变量,那么我无论是在窗体1还是窗体2还是其他地方都可以调用它。而局部变量就不行,比如我在某个窗体定义了一个变量,那么这个变量我就只能在这个窗体中使用。 静态变量,就是当我执行完一个过程后,它的值保存下来了。下次再执行这个过程的时候,使用的值就是新值(即上次过程执行完后产生的值)而动态变量就不会保存那个值。当执行完一个过程后,静态的数值变量会初始化为0,静态的字符串变量会初始化为空字符串

 

7.前向引用之\'函数即变量\'

 

 1def action():
 2     print \'in the action\'
 3     logger()
 4 action()
 5 报错NameError: global name \'logger\' is not defined
 6 
 7 
 8 def logger():
 9     print \'in the logger\'
10 def action():
11     print \'in the action\'
12     logger()
13  
14 action()
15  
16 
17 def action():
18     print \'in the action\'
19     logger()
20 def logger():
21     print \'in the logger\'
22  
23 action() 

函数==变量说明函数的参数和返回值也可以是函数,这点很重要

 

8.嵌套函数和作用域

看上面的标题的意思是,函数还能套函数?of course(1)嵌套函数

 1 name = "Alex"
 2 
 3 def change_name():
 4     name = "Alex2"
 5 
 6     def change_name2():
 7         name = "Alex3"
 8         print("第3层打印",name)
 9 
10     change_name2() #调用内层函数
11     print("第2层打印",name)
12 
13 
14 change_name()
15 print("最外层打印",name)   

注意:
每一次都运行函数hange_name()后才打印

输出:

第3层打印 Alex3
第2层打印 Alex2
最外层打印 Alex

注意:此时,在最外层调用change_name2()会出现什么效果?

没错, 出错了, 为什么呢?

作用域在定义函数时就已经固定住了,不会随着调用位置的改变而改变

(意思是已经作用域确定后就无法更改)

 

(2)作用域固定

作用域在定义函数时就已经固定住了,不会随着调用位置的改变而改变

 

 1 例一:
 2 name=\'alex\'
 3 
 4 def foo():
 5     name=\'lhf\'
 6     def bar():
 7         print(name)
 8     return bar
 9 
10 func=foo()
11 func()
12 
13 
14 例二:
15 name=\'alex\'
16 
17 def foo():
18     name=\'lhf\'
19     def bar():
20         name=\'wupeiqi\'
21         def tt():
22             print(name)
23         return tt
24     return bar
25 
26 func=foo()
27 func()()

 

9.递归调用

(1)递归调用定义

递归调用是一种特殊的嵌套调用,是某个函数调用自己或者是调用其他函数后再次调用自己的,只要函数之间互相调用能产生循环的则一定是递归调用,递归调用一种解决方案,一种是逻辑思想,将一个大工作分为逐渐减小的小工作,比如说一个和尚要搬50块石头,他想,只要先搬走49块,那剩下的一块就能搬完了,然后考虑那49块,只要先搬走48块,那剩下的一块就能搬完了,递归是一种思想,只不过在程序中,就是依靠函数嵌套这个特性来实现了。

在函数内部,可以调用其他函数。如果在调用一个函数的过程中直接或间接调用自身本身

(1)举例

1 def calc(n):                 calc:通过函数指针调用函数。
2     print(n)
3     if int(n / 2) == 0:
4         return n
5     return calc(int(n / 2))
6 calc(10)

输出:

10
5
2
1

(2)递归问路

 1 #_*_coding:utf-8_*_
 2 __author__ = \'Linhaifeng\'
 3 import time
 4 
 5 person_list=[\'alex\',\'wupeiqi\',\'yuanhao\',\'linhaifeng\']
 6 def ask_way(person_list):
 7     print(\'-\'*60)
 8     if len(person_list) == 0:
 9         return \'没人知道\'
10     person=person_list.pop(0)
11     if person == \'linhaifeng\':
12         return \'%s说:我知道,老男孩就在沙河汇德商厦,下地铁就是\' %person
13     print(\'hi 美男[%s],敢问路在何方\' %person)
14     print(\'%s回答道:我不知道,但念你慧眼识猪,你等着,我帮你问问%s...\' %(person,person_list))
15     time.sleep(3)
16     res=ask_way(person_list)
17     # print(\'%s问的结果是: %res\' %(person,res))
18     return res
19 
20 
21 
22 res=ask_way(person_list)
23 
24 print(res)

输出:

hi 美男[alex],敢问路在何方
alex回答道:我不知道,但念你慧眼识猪,你等着,我帮你问问[\'wupeiqi\', \'yuanhao\', \'linhaifeng\']...
------------------------------------------------------------
hi 美男[wupeiqi],敢问路在何方
wupeiqi回答道:我不知道,但念你慧眼识猪,你等着,我帮你问问[\'yuanhao\', \'linhaifeng\']...
------------------------------------------------------------
hi 美男[yuanhao],敢问路在何方
yuanhao回答道:我不知道,但念你慧眼识猪,你等着,我帮你问问[\'linhaifeng\']...
------------------------------------------------------------
linhaifeng说:我知道,老男孩就在沙河汇德商厦,下地铁就是

注释:上面这就是循环问那几个list的人名,知道linhaifeng知道路,再打印出来

(3)递归特性

1. 必须有一个明确的结束条件

2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少

3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)(占内存空间)

堆栈扫盲http://www.cnblogs.com/lln7777/archive/2012/03/14/2396164.html 

尾递归优化:http://egon09.blog.51cto.com/9161406/1842475

 1 data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]
 2 
 3 
 4 def binary_search(dataset, find_num):
 5     print(dataset)
 6 
 7     if len(dataset) > 1:
 8         mid = int(len(dataset) / 2)
 9         if dataset[mid] == find_num:  # find it
10             print("找到数字", dataset[mid])
11         elif dataset[mid] > find_num:  # 找的数在mid左面
12             print("\\033[31;1m找的数在mid[%s]左面\\033[0m" % dataset[mid])
13             return binary_search(dataset[0:mid], find_num)
14         else:  # 找的数在mid右面
15             print("\\033[32;1m找的数在mid[%s]右面\\033[0m" % dataset[mid])
16             return binary_search(dataset[mid + 1:], find_num)
17     else:
18         if dataset[0] == find_num:  # find it
19             print("找到数字啦", dataset[0])
20         else:
21             print("没的分了,要找的数字[%s]不在列表里" % find_num)
22 binary_search(data, 66)

输出:

[1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]
找的数在mid[18]右面
[20, 21, 22, 23, 30, 32, 33, 35]
找的数在mid[30]右面
[32, 33, 35]
找的数在mid[33]右面
[35]
没的分了,要找的数字[66]不在列表里

binary search:二分法检索(binary search)又称折半检索,二分法检索的基本思想是设字典中的元素从小到大有序地存放在数组(array)中。

 

以上是关于Python学习——02-Python基础——4-变量与递归函数的主要内容,如果未能解决你的问题,请参考以下文章

Python学习02Python基础

Python学习——02-Python基础——5-迭代器协议和生成器

Python学习——02-Python基础——2-运算符与基本数据类型——课后作业

Python学习——02-Python基础——7-模块——time与random等常用模块与包

Python学习——02-Python基础——8-面向对象的程序设计——封装绑定方法与非绑定方

02.Python基础