Python Basics---Chapter6 Abstraction (3)


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)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章