Contents
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 asthere 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
The key to the recursive part of binary search is that the sequence must be sorted first
.
Assert statement can be translate to raise-if-not
.
As shown in the code, you can return a function which also has a return statement
.
'/': 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