(Basic Python tutorial) learning notes | Chapter 2 | Abstraction

Source: Internet
Author: User

(Basic Python tutorial) learning notes | Chapter 2 | Abstraction

Chapter 2 Abstraction

------

Laziness is a virtue

Suppose we want to calculate the Fibonacci series (any number is the numerical sequence of the sum of the first two)

>>> Fiber = [] >>> for I in range (8): fiber. append (fibs [-2] + fibs [-1]) # s [-2] + fibs [-1] After two digits, append is added later # after running, the 10 numbers that contain 10 Fibonacci series are >>> S [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
What should I do if I allow user input to change the calculated value?
>>> fibs = [0,1]>>> num = input('Enter number here:')Enter number here:10>>> for i in range(num-2):fibs.append(fibs[-2]+fibs[-1])>>> fibs[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
If this program is frequently used, it should be abstracted, as shown below: The fibs function will be created
num = input('How many numbers do you want? ') print fibs(num)

The program should be very abstract, just like "Download Page, computing frequency, print Word Frequency.
In fact, we can translate this description into Python now.

page  = download_page()freqs = compute_frequencies(page)for word,freq in freqs:    print word, freq

------

Create a function

A function can be called to execute a behavior and return a value.

In general, the built-in callable function can determine whether the function is callable:

>>> import math>>> x = 1>>> y = math.sqrt>>> callable(x)False>>> callable(y)True
Note: callbale () will be replaced by hasattr (func. _ call _) in Python3.0.

Creating a function is the key to organizing a program. How can we define a function? The following is the simplest function.

>>> def hello(name):return 'Hello,' + name + '!'>>> hello('Jerry')'Hello,Jerry!'

If the above Fibonacci is to be written as a function, it is much more convenient. You can input any number.

>>> def fibs(num):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]

Note:

1. The return statement is very important and used to return values from the function. If there is no return value, the return value is None.

>>> def sum(x,y):result = x + y>>> print sum(1,2)None

2. return is equivalent to the break in the program. For example:

Def test (): print 'this is 1 line. 'Return print' This is 2 line' test () # output result >>> This is 1 line.
The second print is not displayed.
------

Record Function

If you want the function to be understood by others, you can use # annotations, and add strings directly to the other one.

If you put the def function directly behind it, it will be part of the function, called the document string.

>>> def square(x):'Calculates the square of the number x'return x*x
You can use the built-in module _ doc _ to view the document.
>>> square.__doc__'Calculates the square of the number x'
The most important and common functions are help () and dir ().
>>> dir(square)['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
>>> help(square)Help on function square in module __main__:square(x)    Calculates the square of the number x

------

Parameter magic

Form parameter: The variable after def is a form parameter.

Real parameter: the value provided by the call function is a real parameter, or a value.

Variables are defined in the function body, as local variables, as global variables.

>>> Def try_to_change (n): n = 'Mr, gumby' >>> name = 'Mrs, Smith '>>> try_to_change (name) # Pass name as a real parameter to the try_to_change function> name # The global variable value remains the same as 'Mrs, Smith'
The string and ancestor are immutable, so they cannot be modified. What if a variable data structure, such as a list, is used as a parameter?
>>> Def change (n): n [0] = 'Mr. gumby '> name = ['Mrs. smith ', 'Mr. jing '] >>> change (name) >>> name # The value has changed ['Mr. gumby', 'Mr. jing ']

This is the difference with the above, where the list has changed:

>>> Name = ['Mrs. smith ', 'Mr. jing ']> n = name # analog transfer parameter> n [0] = 'Mr. gumby' # change the list> name ['Mr. gumby', 'Mr. jing ']
If you do not want to modify it, you have to copy its copy n = name [:]
>>> storage={}>>> storage['first']={}>>> storage['middle']={}>>> storage['last']={}>>> storage{'middle': {}, 'last': {}, 'first': {}}
# Storage: this dictionary storage method has three keys: 'first', 'middle', and 'last '.
Each key corresponds to a dictionary. In the subdictionary, you can use the name as the key and insert the contact list as the value.
>>> storage['first']['Magus']=[me]>>> storage['middle']['Lei']=[me]>>> storage['last']['Hetland']=[me]>>> storage{'middle':   {'Lei': ['Magnus Lei Hetland']}, 'last': {'Hetland': ['Magnus Lei Hetland']}, 'first': {'Magus':  ['Magnus Lei Hetland']}}
A human name list is stored under each key. In this example, the list is only me
If you want to get all the names registered with the intermediate Lei, you can do this:
>>> Storage ['ddle'] ['lei']
['Magnus Lei hetand']
The process is a bit boring. If you want to expand the database and do not know what is stored in it.
For example, if my sister's name
>>> my_sister='Anne Lei Hetland'>>> storage['first'].setdefault('Anne',[]).append(my_sister)>>> storage['middle'].setdefault('Lei',[]).append(my_sister)>>> storage['last'].setdefault('Hetland',[]).append(my_sister)>>> storage['first']['Anne']['Anne Lei Hetland']>>> storage['middle']['Lei']['Magnus Lei Hetland', 'Anne Lei Hetland']
If you want to write a large program to update it, it will become bloated.
The main point of abstraction is to hide the complicated details of updates. This process can be implemented using functions.
The following example describes how to initialize a Data Structure:
>>> def init(data):...     data['first']={}...     data['middle'] = {}...     data['last'] = {}...>>> init(storage)>>> storage{'middle': {}, 'last': {}, 'first': {}}
As you can see, functions perform initialization to make the program easier to read.
What should I do if it is an immutable value, such as a number?
>>> def inc(x): return x+1...>>> i = 10>>> i = inc(i)>>> i11
If you want to change the parameters, put them in the list.
>>> def inc(x):...     x[0] = x[0] + 1...>>> foo = [10]>>> inc(foo)>>> foo[11]
In this way, the code will only return new values, which are fresh.
------
Keyword parameters and default values
The concept of location parameters. Consider the following two functions:
>>> def hello_1(greeting,name):         print "%s,%s!"%(greeting,name)...>>> def hello_2(name,greeting):         print "%s,%s!"%(name,greeting)...
The two codes have the same functions, but the parameter names are reversed.
>>> hello_1('hello','world')hello,world!>>> hello_2('hello','world')hello,world!
Sometimes the Parameter order is hard to remember. To make things easier, you can provide the parameter name.
>>> hello_1(greeting='Hi', name='Jerry')Hi,Jerry!
The parameter name and value must correspond
>>> hello_2(name='Jerry',greeting='Hi')Jerry,Hi!
This type of parameter name provides a keyword parameter. The main role is to clarify the role of each parameter,
This avoids the following strange function calls.
store('Mr. Smith',10,20,13,5)store(patient='Mr. Smith',hour=10,minutes=20,day=13,month=5)
Although I typed a few more words, it was clear that the order of parameters would not affect the program.
The most powerful keyword parameter is that the default value can be provided with the function.
>>> Def hello_3 (greeting = 'hello', name = 'World'):... print '% s, % s! '% (Greeting, name)... >>> hello_3 () # If no parameter is added, the default value Hello, World! >>> Hello_3 ('greeting ') # values greeting, World! >>> Hello_3 ('greeting ', 'Universe') # provide greeting, universe! # If you only want to provide the name, make greeting default >>> hello_3 (name = 'sherry') Hello, Sherry!
The location parameter and keyword parameter can be used together to put the location parameter above.
Note:
Unless you fully understand the functions and meanings of the program, you should avoid mixing location and keyword parameters. Generally, the parameter writing method mentioned above is used only when the number of mandatory parameters is less than the number of parameters with default values that can be modified.
>>> def hello_4(name,greeting='Hello',punctuation='!'):...     print '%s, %s%s' % (greeting,name,punctuation)...>>> hello_4('Jerry')Hello, Jerry!>>> hello_4('Jerry','Howdy')Howdy, Jerry!>>> hello_4('Jerry','Howdy','...')Howdy, Jerry...>>> hello_4('Jerry',punctuation='.')Hello, Jerry.>>> hello_4('Jerry',greeting='Top of the morning to ya')Top of the morning to ya, Jerry!>>> hello_4()Traceback (most recent call last):  File "
 
  ", line 1, in ?TypeError: hello_4() takes at least 1 argument (0 given)
 

# If the last name also uses the default value, the above exception will not occur.

------

Collection Parameters

Sometimes it is necessary to provide multiple parameters. How can this problem be solved? Simple

>>> def print_parms(*parms):...     print parms...
# If one parameter is set, it will be printed as the ancestor with a comma in it
>>> print_parms('Hello')('Hello',)>>> print_parms(1,2,3)(1, 2, 3)
# Put all the parameters in the * sign before parms in the same ancestor and use it.
Can we combine common parameters with collected parameters? Of course.
>>> def print_parms_2(title,*parms):...     print title...     print parms...>>> print_parms_2('Parms:',1,2,3)Parms:(1, 2, 3)
# Here, * becomes the parameter for collecting other locations
>>> print_parms_2('Nothing:')Nothing:()
Indeed, this is very useful. Can we process keyword parameters?
>>> print_parms_2('hmm...',someting=42)Traceback (most recent call last):  File "
 
  ", line 1, in ?TypeError: print_parms_2() got an unexpected keyword argument 'someting'
 
We can see that this should not work. How can this problem be achieved? "**" Is required "**"
>>> def print_parms_3(**parms):...     print parms...>>> print_parms_3(x=1,y=2,z=3){'y': 2, 'x': 1, 'z': 3}
# The returned result is a dictionary instead of a ancestor.
What if I put * And ** together?
>>> def print_parms_4(x,y,z=3,*pospar,**keypar):...     print x,y,z...     print pospar...     print keypar...>>> print_parms_4(1,2,3,5,6,7,foo=1,bar=2)1 2 3(5, 6, 7){'foo': 1, 'bar': 2}

------

Reversal Process

So how to use? Let's look at the following simple example:

>>> Def add (x, y): return x + y... >>> parms = (1, 2) # The following error occurs:> add (parms) Traceback (most recent call last): File"
 
  
", Line 1, in? TypeError: add () takes exactly 2 arguments (1 given) # This is required. add a number * Before It >>> add (* parms) 3
 
# Dictionary calls
>>> def hello_3(greeting='Hello',name='World'):...     print '%s,%s!' % (greeting,name)...>>> params = {'name':'Sir Robin','greeting':'Well met'}>>> hello_3(**params)Well met,Sir Robin!
# Let's take a look at the following: Add a pair * and not add a pair **
>>> def with_star(**kwd):...     print kwd['name'],'is',kwd['age'],'years old!'...>>> def without_star(kwd):...     print kwd['name'],'is',kwd['age'],'years old!'...>>> args = {'name':'Mr. Gumby','age':35}>>> with_star(**args)Mr. Gumby is 35 years old!>>> without_star(args)Mr. Gumby is 35 years old!
# It can be seen that the two are in the same situation, so * only define the function (allow an indefinite number of parameters)

And call (segmentation dictionary or sequence.

Note:

It is useful to pass parameters using the concatenation (Splicing) operator, because there is no need to worry about the number of parameters

>>> def foo(x,y,z,m=0,n=0):...     print x,y,z,m,n...>>> def call_foo(*arg,**kwds):...     print 'Calling foo'...     foo(*arg,**kwds)
------

Exercise parameters:

def story(**kwds):    return 'Once upon a time. There was a ' \'%(job)s called %(name)s.' % kwdsdef power(x,y,*others):    if others:        print 'Received redundant parameters:', others    return pow(x,y)def interval(start,stop=None,step=1):    'Imitates range() for step>0'    if stop is None:        start,stop = 0,start    result = []    i = start    while i < stop:        result.append(i)        i +=step    return resultprint story(job='king',name='Gumby')print story(name='Jerry',job='king')params = {'job':'language','name':'Python'}print story(**params)del params['job']print story(job='stroke of genius',**params)print power(2,3)print power(3,2)print power(y=3,x=2)params =(5,)*2print power(*params)print power(2,3,'Hello,World!')print interval(10)print interval(1,5)print interval(3,12,4)print power(*interval(3,7))
Output result:

D: \> python Python. py

Once upon a time. There was a king called Gumby.Once upon a time. There was a king called Jerry.Once upon a time. There was a language called Python.Once upon a time. There was a stroke of genius called Python.8983125Received redundant parameters: ('Hello,World!',)8[0, 1, 2, 3, 4, 5, 6, 7, 8, 9][1, 2, 3, 4][3, 7, 11]Received redundant parameters: (5, 6)81

------

Scope

>>> x = 1>>> scope = vars()>>> scope['x']1>>> scope['x'] +=1>>> x2
# Valid only in the function body
>>> def foo(): x = 42...>>> x = 1>>> foo()>>> x1>>> def output(x): print x...>>> x = 1>>> y = 2>>> output(y)2
# Using external variables in the function body
>>> def combine(param): print param+external...>>> external = 'berry'>>> combine('Shrub')Shrubberry
WARN: referencing variables like this is the cause of many errors:

What if the names of local variables and global variables are the same?

>>> def comb(param):...     print param + globals()['param']...>>> param='Sherry'>>> comb('Jerry->')Jerry->Sherry
So how to change global variables?
>>> x = 1>>> def change_global():...     global x...     x +=1...>>> x1>>> change_global()>>> x2

------

Nested scope: one function is nested in another function.

>>> def foo():...     def bar():...         print 'Hello,World!'...     bar()...>>> foo()Hello,World!

>>> def multiplier(factor):...     def multiplyByFactor(number):...         return number*factor...     return multiplyByFactor...>>> double = multiplier(2)>>> double(5)10>>> triple = multiplier(3)>>> triple(3)9>>> multiplier(5)(4)20
# Let's take a look
>>> def A(x):        def B(y):           def C(z):               return x+y+z           return C        return B>>> A(1)(2)(3)6

------

Recursion: Call yourself. The following is the simplest example of infinite recursion:

>>> Def A (): return A () >>> A () # infinite loop. The maximum recursive depth error is returned after all memory resources are consumed, similar to while True File"
 
  
", Line 2, in A return A () RuntimeError: maximum recursion depth exceeded
 
# Use break and return in combination to avoid infinite Loops

# Every time a function is called, a new namespace is generated, which means that when the function calls itself, two functions will run simultaneously.

Two classics: factorial and power

N * (n-1) * (n-2)... 2*1, can be implemented using common functions

>>> def factorial(n):result = nfor i in range(1,n):result *=ireturn result>>> factorial(3)6
It can also be implemented using recursion:
>>> Def factorial (n): if n = 1: # The factorial of 1 is 1 return 1 else: # The factorial greater than 1 is n * (n-1 )! Return n * factorial (n-1)

How to Implement power?

>>> Def power (x, n): # general result = 1for I in range (n): result * = xreturn result >>> power (2, 3) 8
>>> Def power (x, n): # factorial implementation if n = 0: return 1 else: return x * power (x, n-1) >>> power (2, 3) 8
------

New functions in this Chapter

Map (func, seq [, seq,]) applies functions to each element in the sequence.

Filter (func, seq) returns a list of elements whose functions are real elements.

Reduce (func, seq [, initial]) is equivalent to func (seq [0], seq [1], seq [2],...)

Sum (seq) returns the sum of all elements in seq

Apply (func [, args [, kwargs]) to call a function and provide parameters

------

------

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.