Python Basics---Chapter6 Abstraction (3)

本文深入探讨了Python中变量的作用域概念,包括全局与局部变量的区别,以及如何使用globals()和locals()函数。此外,文章还讲解了嵌套作用域及递归函数的应用,通过经典案例如阶乘和幂运算,以及二分搜索算法,展示了递归的高效性和可读性。


Scoping

1. vars()

vars() : return the scoping dictionary of a varible.

x=1
scope=vars()
scope['x']
>>>1

Attention!!: the varible name in the scoping dict is stored as a string.

2. The scope of varibles

The scope of the varible is also called namespace, in addition to global scope , each function creats a new one called local scope . Accordingly, the varibles are called global varibles and local varibles .

3. globals() and locals()

globals() : return a dictionary of global varibles.
locals() :return a dictionary of local varibles.
The use of these two functions is just like scope().

4. Read global varibles inside a function

  • You can read (just read) the value of a global varible inside a function, as long as there is no varible or parameter with the same name inside the function.
def combine(parameter):
   print(parameter+external)
external='berry'
combine('Shrub') 
>>>Shrubberry

Attention!! : Read global varibles inside a function is a source of bugs!!!

  • If there is varible or parameter with the same name inside the function, and you still want to access a global varible inside the function, you can use globals().
def combine(parameter):
    print(parameter+globals()['parameter'])
parameter='berry'
combine('Shrub')
>>>Shrubberry

5. Nested Scope

(1)

def mutiplier(factor):
    def mutiplybyfactor(number):
        return number*factor
    return mutiplybyfactor# without ()
double=mutiplier(10)
double(10)
>>>100

The varible factor is the outer scope varible of mutiplyby factor.

mutiplier returns function mutiplybyfactor, pay attention to the form (without ()).

(2)

def mutiplier(factor):
    def mutiplybyfactor(number):
        return number*factor
    return mutiplybyfactor(number)#with ()
double=mutiplier(10)
double(10)
>>>---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-87-c3681247e68a> in <module>()
      3         return number*factor
      4     return mutiplybyfactor(number)
----> 5 double=mutiplier(10)
      6 double(10)

<ipython-input-87-c3681247e68a> in mutiplier(factor)
      2     def mutiplybyfactor(number):
      3         return number*factor
----> 4     return mutiplybyfactor(number)
      5 double=mutiplier(10)
      6 double(10)

NameError: name 'number' is not defined

Attention!!: in nested function definition, the inner scope varibles cannot be used in the outer scope.


Recursion

  • A useful recursive functionusually consists of the following parts:
    (1) A base case (for the smallest possible problem) when the function returns a value directly.
    (2) A recursive case, which contains one or more recursive calls on smaller parts of the problem.

1. Two Classics: Factorial and Power

  • Factorial: n(n-1)(n-2)(n-3)…321
    (1) If n==1 returen 1 —> base case
    (2) n>1, return n*factorial(n-1) —> recursive case
def factorial(n):
    if n==1:
        return 1
    else:
        return n*factorial(n-1)
factorial(6)
>>>720
  • Power: xn=x * xn-1
    (1)if n==0, return 1 —> base case
    (2) n>1,return x * xn-1 —> recursive case
def power(x,n):
    if n==0:
        return 1
    else:
        return x*power(x,n-1)
power(2,10)
>>>1024

You can use loops to implement these two functions, but recursion is much more readable.

2. A Classic Algorithm: Binary Search

  • The two parts of binary search are :
    (1) If the lower and upper limits are the same, and they both refer to the right position of the number, then return the number.
    (2)Otherwise, find the middle of the lower and upper limits, and find out whether the number is in the right half or left half. Keep repeating this progress,
def bin_search(sequence,number,lower,upper):
    if lower==upper:
        assert number==sequence[upper]# the use of assert
        return print('The index of {} is:{}'.format(number,upper))# You can return a function with returning 
    else:
        middle=(lower+upper)//2 # 
        if number>sequence[middle]:
            return bin_search(sequence,number,middle+1,upper)
        else:
            return bin_search(sequence,number,lower,middle)
digit=[34,89,22,1,3,67,98,31,2,12,99,108,45,237,156,96,9,6,11]
digit.sort()
digit
>>>[1, 2, 3, 6, 9, 11, 12, 22, 31, 34, 45, 67, 89, 96, 98, 99, 108, 156, 237]
bin_search(digit,237,0,len(digit)-1)
>>>The index of 237 is: 18
  • For sorted sequence search

The key to the recursive part of binary search is that the sequence must be sorted first.

  • Assert

Assert statement can be translate to raise-if-not.

  • Return a function

As shown in the code, you can return a function which also has a return statement.

  • Previous on calculation operators

'/': float division.

1/2
>>>0.5
2/2
>>>1.0
5/2
>>>2.5

'//': integer division.

1//2
>>>0
2/2
>>>1
5//2
>>>2
  • list.sort() and len(sequence)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值