1 <html> |
|
2 <head> |
|
3 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> |
|
4 <title></title> |
|
5 <link rel="stylesheet" href="hgbook.css" type="text/css"> |
|
6 <meta name="generator" content="DocBook XSL Stylesheets V1.75.1"> |
|
7 </head> |
|
8 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><span style="color: red"><html><span style="color: red"><body><span style="color: red"><document><span style="color: red"><title>Functional Approach</title></span><span style="color: red"><paragraph><span class="emphasis"><em>Functions</em></span> allow us to enclose a set of statements and call the function again |
|
9 and again instead of repeating the group of statements everytime. Functions also |
|
10 allow us to isolate a piece of code from all the other code and provides the |
|
11 convenience of not polluting the global variables.</paragraph></span><span style="color: red"><paragraph><span class="emphasis"><em>Function</em></span> in python is defined with the keyword <span style="color: red"><strong>def</strong></span> followed by the name |
|
12 of the function, in turn followed by a pair of parenthesis which encloses the |
|
13 list of parameters to the function. The definition line ends with a ':'. The |
|
14 definition line is followed by the body of the function intended by one block. |
|
15 The <span class="emphasis"><em>Function</em></span> must return a value:</paragraph></span><span style="color: red"><literal_block>def factorial(n): |
|
16 fact = 1 |
|
17 for i in range(2, n): |
|
18 fact *= i |
|
19 |
|
20 return fact</literal_block></span><span style="color: red"><paragraph>The code snippet above defines a function with the name factorial, takes the |
|
21 number for which the factorial must be computed, computes the factorial and |
|
22 returns the value.</paragraph></span><span style="color: red"><paragraph>A <span class="emphasis"><em>Function</em></span> once defined can be used or called anywhere else in the program. We |
|
23 call a fucntion with its name followed by a pair of parenthesis which encloses |
|
24 the arguments to the function.</paragraph></span><span style="color: red"><paragraph>The value that function returns can be assigned to a variable. Let's call the |
|
25 above function and store the factorial in a variable:</paragraph></span><span style="color: red"><literal_block>fact5 = factorial(5)</literal_block></span><span style="color: red"><paragraph>The value of fact5 will now be 120, which is the factorial of 5. Note that we |
|
26 passed 5 as the argument to the function.</paragraph></span><span style="color: red"><paragraph>It may be necessary to document what the function does, for each of the function |
|
27 to help the person who reads our code to understand it better. In order to do |
|
28 this Python allows the first line of the function body to be a string. This |
|
29 string is called as <span class="emphasis"><em>Documentation String</em></span> or <span class="emphasis"><em>docstring</em></span>. <span class="emphasis"><em>docstrings</em></span> prove |
|
30 to be very handy since there are number of tools which can pull out all the |
|
31 docstrings from Python functions and generate the documentation automatically |
|
32 from it. <span class="emphasis"><em>docstrings</em></span> for functions can be written as follows:</paragraph></span><span style="color: red"><literal_block>def factorial(n): |
|
33 'Returns the factorial for the number n.' |
|
34 fact = 1 |
|
35 for i in range(2, n): |
|
36 fact *= i |
|
37 |
|
38 return fact</literal_block></span><span style="color: red"><paragraph>An important point to note at this point is that, a function can return any |
|
39 Python value or a Python object, which also includes a <span class="emphasis"><em>Tuple</em></span>. A <span class="emphasis"><em>Tuple</em></span> is |
|
40 just a collection of values and those values themselves can be of any other |
|
41 valid Python datatypes, including <span class="emphasis"><em>Lists</em></span>, <span class="emphasis"><em>Tuples</em></span>, <span class="emphasis"><em>Dictionaries</em></span> among other |
|
42 things. So effectively, if a function can return a tuple, it can return any |
|
43 number of values through a tuple</paragraph></span><span style="color: red"><paragraph>Let us write a small function to swap two values:</paragraph></span><span style="color: red"><literal_block>def swap(a, b): |
|
44 return b, a |
|
45 |
|
46 c, d = swap(a, b)</literal_block></span><div class="section" title="1. Function scope"> |
|
47 <div class="titlepage"><div><div><h2 class="title" style="clear: both"> |
|
48 <a name="id2981898"></a>1. Function scope</h2></div></div></div> |
|
49 <span style="color: red"><paragraph>The variables used inside the function are confined to the function's scope |
|
50 and doesn't pollute the variables of the same name outside the scope of the |
|
51 function. Also the arguments passed to the function are passed by-value if |
|
52 it is of basic Python data type:</paragraph></span><span style="color: red"><literal_block>def cant_change(n): |
|
53 n = 10 |
|
54 |
|
55 n = 5 |
|
56 cant_change(n)</literal_block></span><span style="color: red"><paragraph>Upon running this code, what do you think would have happened to value of n |
|
57 which was assigned 5 before the function call? If you have already tried out |
|
58 that snippet on the interpreter you already know that the value of n is not |
|
59 changed. This is true of any immutable types of Python like <span class="emphasis"><em>Numbers</em></span>, <span class="emphasis"><em>Strings</em></span> |
|
60 and <span class="emphasis"><em>Tuples</em></span>. But when you pass mutable objects like <span class="emphasis"><em>Lists</em></span> and <span class="emphasis"><em>Dictionaries</em></span> |
|
61 the values are manipulated even outside the function:</paragraph></span><span style="color: red"><literal_block>>>> def can_change(n): |
|
62 ... n[1] = James |
|
63 ... |
|
64 |
|
65 >>> name = ['Mr.', 'Steve', 'Gosling'] |
|
66 >>> can_change(name) |
|
67 >>> name |
|
68 ['Mr.', 'James', 'Gosling']</literal_block></span><span style="color: red"><paragraph>If nothing is returned by the function explicitly, Python takes care to return |
|
69 None when the funnction is called.</paragraph></span> |
|
70 </div> |
|
71 <div class="section" title="2. Default Arguments"> |
|
72 <div class="titlepage"><div><div><h2 class="title" style="clear: both"> |
|
73 <a name="id2981970"></a>2. Default Arguments</h2></div></div></div> |
|
74 <span style="color: red"><paragraph>There may be situations where we need to allow the functions to take the |
|
75 arguments optionally. Python allows us to define function this way by providing |
|
76 a facility called <span class="emphasis"><em>Default Arguments</em></span>. For example, we need to write a function |
|
77 that returns a list of fibonacci numbers. Since our function cannot generate an |
|
78 infinite list of fibonacci numbers, we need to specify the number of elements |
|
79 that the fibonacci sequence must contain. Suppose, additionally, we want to the |
|
80 function to return 10 numbers in the sequence if no option is specified we can |
|
81 define the function as follows:</paragraph></span><span style="color: red"><literal_block>def fib(n=10): |
|
82 fib_list = [0, 1] |
|
83 for i in range(n - 2): |
|
84 next = fib_list[-2] + fib_list[-1] |
|
85 fib_list.append(next) |
|
86 return fib_list</literal_block></span><span style="color: red"><paragraph>When we call this function, we can optionally specify the value for the |
|
87 parameter n, during the call as an argument. Calling with no argument and |
|
88 argument with n=5 returns the following fibonacci sequences:</paragraph></span><span style="color: red"><literal_block>fib() |
|
89 [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] |
|
90 fib(5) |
|
91 [0, 1, 1, 2, 3]</literal_block></span> |
|
92 </div> |
|
93 <div class="section" title="3. Keyword Arguments"> |
|
94 <div class="titlepage"><div><div><h2 class="title" style="clear: both"> |
|
95 <a name="id2981995"></a>3. Keyword Arguments</h2></div></div></div> |
|
96 <span style="color: red"><paragraph>When a function takes a large number of arguments, it may be difficult to |
|
97 remember the order of the parameters in the function definition or it may |
|
98 be necessary to pass values to only certain parameters since others take |
|
99 the default value. In either of these cases, Python provides the facility |
|
100 of passing arguments by specifying the name of the parameter as defined in |
|
101 the function definition. This is known as <span class="emphasis"><em>Keyword Arguments</em></span>.</paragraph></span><span style="color: red"><paragraph>In a function call, <span class="emphasis"><em>Keyword arguments</em></span> can be used for each argument, in the |
|
102 following fashion:</paragraph></span><span style="color: red"><literal_block>argument_name=argument_value |
|
103 Also denoted as: keyword=argument |
|
104 |
|
105 def wish(name='World', greetings='Hello'): |
|
106 print "%s, %s!" % (greetings, name)</literal_block></span><span style="color: red"><paragraph>This function can be called in one of the following ways. It is important to |
|
107 note that no restriction is imposed in the order in which <span class="emphasis"><em>Keyword arguments</em></span> |
|
108 can be specified. Also note, that we have combined <span class="emphasis"><em>Keyword arguments</em></span> with |
|
109 <span class="emphasis"><em>Default arguments</em></span> in this example, however it is not necessary:</paragraph></span><span style="color: red"><literal_block>wish(name='Guido', greetings='Hey') |
|
110 wish(greetings='Hey', name='Guido')</literal_block></span><span style="color: red"><paragraph>Calling functions by specifying arguments in the order of parameters specified |
|
111 in the function definition is called as <span class="emphasis"><em>Positional arguments</em></span>, as opposed to |
|
112 <span class="emphasis"><em>Keyword arguments</em></span>. It is possible to use both <span class="emphasis"><em>Positional arguments</em></span> and |
|
113 <span class="emphasis"><em>Keyword arguments</em></span> in a single function call. But Python doesn't allow us to |
|
114 bungle up both of them. The arguments to the function, in the call, must always |
|
115 start with <span class="emphasis"><em>Positional arguments</em></span> which is in turn followed by <span class="emphasis"><em>Keyword |
|
116 arguments</em></span>:</paragraph></span><span style="color: red"><literal_block>def my_func(x, y, z, u, v, w): |
|
117 # initialize variables. |
|
118 ... |
|
119 # do some stuff |
|
120 ... |
|
121 # return the value</literal_block></span><span style="color: red"><paragraph>It is valid to call the above functions in the following ways:</paragraph></span><span style="color: red"><literal_block>my_func(10, 20, 30, u=1.0, v=2.0, w=3.0) |
|
122 my_func(10, 20, 30, 1.0, 2.0, w=3.0) |
|
123 my_func(10, 20, z=30, u=1.0, v=2.0, w=3.0) |
|
124 my_func(x=10, y=20, z=30, u=1.0, v=2.0, w=3.0)</literal_block></span><span style="color: red"><paragraph>Following lists some of the invalid calls:</paragraph></span><span style="color: red"><literal_block>my_func(10, 20, z=30, 1.0, 2.0, 3.0) |
|
125 my_func(x=10, 20, z=30, 1.0, 2.0, 3.0) |
|
126 my_func(x=10, y=20, z=30, u=1.0, v=2.0, 3.0)</literal_block></span> |
|
127 </div> |
|
128 <div class="section" title="4. Parameter Packing and Unpacking"> |
|
129 <div class="titlepage"><div><div><h2 class="title" style="clear: both"> |
|
130 <a name="id2982116"></a>4. Parameter Packing and Unpacking</h2></div></div></div> |
|
131 <span style="color: red"><paragraph>The positional arguments passed to a function can be collected in a tuple |
|
132 parameter and keyword arguments can be collected in a dictionary. Since keyword |
|
133 arguments must always be the last set of arguments passed to a function, the |
|
134 keyword dictionary parameter must be the last parameter. The function definition |
|
135 must include a list explicit parameters, followed by tuple paramter collecting |
|
136 parameter, whose name is preceded by a <span style="color: red"><strong>*</strong></span>, for collecting positional |
|
137 parameters, in turn followed by the dictionary collecting parameter, whose name |
|
138 is preceded by a <span style="color: red"><strong>**</strong></span></paragraph></span><span style="color: red"><literal_block>def print_report(title, *args, **name): |
|
139 """Structure of *args* |
|
140 (age, email-id) |
|
141 Structure of *name* |
|
142 { |
|
143 'first': First Name |
|
144 'middle': Middle Name |
|
145 'last': Last Name |
|
146 } |
|
147 """ |
|
148 |
|
149 print "Title: %s" % (title) |
|
150 print "Full name: %(first)s %(middle)s %(last)s" % name |
|
151 print "Age: %d\nEmail-ID: %s" % args</literal_block></span><span style="color: red"><paragraph>The above function can be called as. Note, the order of keyword parameters can |
|
152 be interchanged:</paragraph></span><span style="color: red"><literal_block>>>> print_report('Employee Report', 29, 'johny@example.com', first='Johny', |
|
153 last='Charles', middle='Douglas') |
|
154 Title: Employee Report |
|
155 Full name: Johny Douglas Charles |
|
156 Age: 29 |
|
157 Email-ID: johny@example.com</literal_block></span><span style="color: red"><paragraph>The reverse of this can also be achieved by using a very identical syntax while |
|
158 calling the function. A tuple or a dictionary can be passed as arguments in |
|
159 place of a list of <span class="emphasis"><em>Positional arguments</em></span> or <span class="emphasis"><em>Keyword arguments</em></span> respectively |
|
160 using <span style="color: red"><strong>*</strong></span> or <span style="color: red"><strong>**</strong></span></paragraph></span><span style="color: red"><literal_block>def print_report(title, age, email, first, middle, last): |
|
161 print "Title: %s" % (title) |
|
162 print "Full name: %s %s %s" % (first, middle, last) |
|
163 print "Age: %d\nEmail-ID: %s" % (age, email) |
|
164 |
|
165 >>> args = (29, 'johny@example.com') |
|
166 >>> name = { |
|
167 'first': 'Johny', |
|
168 'middle': 'Charles', |
|
169 'last': 'Douglas' |
|
170 } |
|
171 >>> print_report('Employee Report', *args, **name) |
|
172 Title: Employee Report |
|
173 Full name: Johny Charles Douglas |
|
174 Age: 29 |
|
175 Email-ID: johny@example.com</literal_block></span> |
|
176 </div> |
|
177 <div class="section" title="5. Nested Functions and Scopes"> |
|
178 <div class="titlepage"><div><div><h2 class="title" style="clear: both"> |
|
179 <a name="id2982188"></a>5. Nested Functions and Scopes</h2></div></div></div> |
|
180 <span style="color: red"><paragraph>Python allows nesting one function inside another. This style of programming |
|
181 turns out to be extremely flexible and powerful features when we use <span class="emphasis"><em>Python |
|
182 decorators</em></span>. We will not talk about decorators is beyond the scope of this |
|
183 course. If you are interested in knowing more about <span class="emphasis"><em>decorator programming</em></span> in |
|
184 Python you are suggested to read:</paragraph></span><span style="color: red"><line_block><span style="color: red"><line><div class="reference"> |
|
185 <div class="titlepage"><hr></div>http://avinashv.net/2008/04/python-decorators-syntactic-sugar/</div></line></span><span style="color: red"><line><div class="reference"> |
|
186 <div class="titlepage"><hr></div>http://personalpages.tds.net/~kent37/kk/00001.html</div></line></span></line_block></span><span style="color: red"><paragraph>However, the following is an example for nested functions in Python:</paragraph></span><span style="color: red"><literal_block>def outer(): |
|
187 print "Outer..." |
|
188 def inner(): |
|
189 print "Inner..." |
|
190 print "Outer..." |
|
191 inner() |
|
192 |
|
193 >>> outer()</literal_block></span> |
|
194 </div> |
|
195 <div class="section" title="6. map, reduce and filter functions"> |
|
196 <div class="titlepage"><div><div><h2 class="title" style="clear: both"> |
|
197 <a name="id2982258"></a>6. map, reduce and filter functions</h2></div></div></div> |
|
198 <span style="color: red"><paragraph>Python provides several built-in functions for convenience. The <span style="color: red"><strong>map()</strong></span>, |
|
199 <span style="color: red"><strong>reduce()</strong></span> and <span style="color: red"><strong>filter()</strong></span> functions prove to be very useful with sequences like |
|
200 <span class="emphasis"><em>Lists</em></span>.</paragraph></span><span style="color: red"><paragraph>The <span style="color: red"><strong>map</strong></span> (<span class="emphasis"><em>function</em></span>, <span class="emphasis"><em>sequence</em></span>) function takes two arguments: <span class="emphasis"><em>function</em></span> |
|
201 and a <span class="emphasis"><em>sequence</em></span> argument. The <span class="emphasis"><em>function</em></span> argument must be the name of the |
|
202 function which in turn takes a single argument, the individual element of the |
|
203 <span class="emphasis"><em>sequence</em></span>. The <span style="color: red"><strong>map</strong></span> function calls <span class="emphasis"><em>function(item)</em></span>, for each item in the |
|
204 sequence and returns a list of values, where each value is the value returned |
|
205 by each call to <span class="emphasis"><em>function(item)</em></span>. <span style="color: red"><strong>map()</strong></span> function allows to pass more than |
|
206 one sequence. In this case, the first argument, <span class="emphasis"><em>function</em></span> must take as many |
|
207 arguments as the number of sequences passed. This function is called with each |
|
208 corresponding element in the each of the sequences, or <span style="color: red"><strong>None</strong></span> if one of the |
|
209 sequence is exhausted:</paragraph></span><span style="color: red"><literal_block>def square(x): |
|
210 return x*x |
|
211 |
|
212 >>> map(square, [1, 2, 3, 4]) |
|
213 [1, 4, 9, 16] |
|
214 |
|
215 def mul(x, y): |
|
216 return x*y |
|
217 |
|
218 >>> map(mul, [1, 2, 3, 4], [6, 7, 8, 9])</literal_block></span><span style="color: red"><paragraph>The <span style="color: red"><strong>filter</strong></span> (<span class="emphasis"><em>function</em></span>, <span class="emphasis"><em>sequence</em></span>) function takes two arguments, similar to |
|
219 the <span style="color: red"><strong>map()</strong></span> function. The <span style="color: red"><strong>filter</strong></span> function calls <span class="emphasis"><em>function(item)</em></span>, for each |
|
220 item in the sequence and returns all the elements in the sequence for which |
|
221 <span class="emphasis"><em>function(item)</em></span> returned True:</paragraph></span><span style="color: red"><literal_block>def even(x): |
|
222 if x % 2: |
|
223 return True |
|
224 else: |
|
225 return False |
|
226 |
|
227 >>> filter(even, range(1, 10)) |
|
228 [1, 3, 5, 7, 9]</literal_block></span><span style="color: red"><paragraph>The <span style="color: red"><strong>reduce</strong></span> (<span class="emphasis"><em>function</em></span>, <span class="emphasis"><em>sequence</em></span>) function takes two arguments, similar to |
|
229 <span style="color: red"><strong>map</strong></span> function, however multiple sequences are not allowed. The <span style="color: red"><strong>reduce</strong></span> |
|
230 function calls <span class="emphasis"><em>function</em></span> with first two consecutive elements in the sequence, |
|
231 obtains the result, calls <span class="emphasis"><em>function</em></span> with the result and the subsequent element |
|
232 in the sequence and so on until the end of the list and returns the final result:</paragraph></span><span style="color: red"><literal_block>def mul(x, y): |
|
233 return x*y |
|
234 |
|
235 >>> reduce(mul, [1, 2, 3, 4]) |
|
236 24</literal_block></span><div class="section" title="6.1. List Comprehensions"> |
|
237 <div class="titlepage"><div><div><h3 class="title"> |
|
238 <a name="id2982429"></a>6.1. List Comprehensions</h3></div></div></div> |
|
239 <span style="color: red"><paragraph>List Comprehension is a convenvience utility provided by Python. It is a |
|
240 syntatic sugar to create <span class="emphasis"><em>Lists</em></span>. Using <span class="emphasis"><em>List Comprehensions</em></span> one can create |
|
241 <span class="emphasis"><em>Lists</em></span> from other type of sequential data structures or other <span class="emphasis"><em>Lists</em></span> itself. |
|
242 The syntax of <span class="emphasis"><em>List Comprehensions</em></span> consists of a square brackets to indicate |
|
243 the result is a <span class="emphasis"><em>List</em></span> within which we include at least one <span style="color: red"><strong>for</strong></span> clause and |
|
244 multiple <span style="color: red"><strong>if</strong></span> clauses. It will be more clear with an example:</paragraph></span><span style="color: red"><literal_block>>>> num = [1, 2, 3] |
|
245 >>> sq = [x*x for x in num] |
|
246 >>> sq |
|
247 [1, 4, 9] |
|
248 >>> all_num = [1, 2, 3, 4, 5, 6, 7, 8, 9] |
|
249 >>> even = [x for x in all_num if x%2 == 0]</literal_block></span><span style="color: red"><paragraph>The syntax used here is very clear from the way it is written. It can be |
|
250 translated into english as, "for each element x in the list all_num, |
|
251 if remainder of x divided by 2 is 0, add x to the list."</paragraph></span> |
|
252 </div> |
|
253 </div></document></span></body></span></html></span></body> |
|
254 </html> |
|