Jul 26, 2008

Python Manace: Control Flow I - python tutorial

Free Web Hosting, No Ads > CONTRIBUTE > Computers > Programming Languages > Others

free web hosting

Python Manace: Control Flow I - python tutorial

marekdudek
Hello

This is the first part of my Python tutorial. The code is pretty self-explanatory so few comments should be enough. If not - let me know.
Tutorial assumes that You have already Python installed. Python 2.4 should be enough.

Let's go, then.

CODE
#! /usr/bin/env python
# -*- coding: utf-8 -*-

import math

def squareRoot_1( lst ) :
"""Returns list of square roots.

No negative number validation.
Allows fractions in result.
"""
result = []
for el in lst :
sqrtFloat = math.sqrt( el )
result.append( sqrtFloat )
return result

def squareRoot_2( lst ) :
'''Returns list of square roots.

No negative number validation.
Omits fractions in result.
'''
result = []
for el in lst :
sqrtFloat = math.sqrt( el )
if int( sqrtFloat ** 2 ) != el :
continue
result.append( sqrtFloat )
return result

def squareRoot_3( lst ) :
result = []
for el in lst :
if el < 0 :
break
sqrtFloat = math.sqrt( el )
result.append( sqrtFloat )
return result

def squareRoot_4( lst ) :
result = []
for el in lst :
sqrtFloat = math.sqrt( el )
result.append( sqrtFloat )
else :
return result

def squareRoot_5( lst ) :
result = []
for el in lst :
sqrtFloat = math.sqrt( el )
if int( sqrtFloat ** 2 ) != el :
continue
result.append( sqrtFloat )
else :
return result

def squareRoot_6( lst ) :
result = []
for el in lst :
if el < 0 :
break
sqrtFloat = math.sqrt( el )
result.append( sqrtFloat )
else :
return result

def testForLoop() :

numbers = [ 1.0 , 2.0 , 3.0 , 4.0 , 5.0 ]
squares = [ 1 , 4 , 9 , 16 , 25 ]

assert squareRoot_1( squares ) == numbers
assert squareRoot_1( [ 1 , 6.25 , 9 , 16 , 25 ] ) == [ 1.0 , 2.5 , 3.0 , 4.0 , 5.0 ]

try :
squareRoot_1( [ 1 , 4 , -9 , 16 , 25 ] ) # error at -9
assert False, "Processing cannot get here"
except ValueError, e :
pass

assert squareRoot_2( squares ) == numbers
assert squareRoot_2( [ 1 , 6.25 , 9 , 16 , 25 ] ) == [ 1.0 , 3.0 , 4.0 , 5.0 ]

try :
squareRoot_2( [ 1 , 4 , -9 , 16 , 25 ] ) # error at -9
assert False, 'Processing cannot get here'
except ValueError, e :
pass

assert squareRoot_3( squares ) == numbers
assert squareRoot_3( [ 1 , 4 , -9 , 16 , 25 ] ) == [ 1.0 , 2.0 ]
assert squareRoot_3( [ 1 , 6.25 , 9 , 16 , 25 ] ) == [ 1.0 , 2.5 , 3.0 , 4.0 , 5.0 ]

assert squareRoot_4( squares ) == numbers
assert squareRoot_4( [ 1 , 6.25 , 9 , 16 , 25 ] ) == [ 1.0 , 2.5 , 3.0 , 4.0 , 5.0 ]

try :
squareRoot_4( [ 1 , 4 , -9 , 16 , 25 ] ) # error at -9
assert False
except ValueError, e :
pass

assert squareRoot_5( squares ) == numbers
assert squareRoot_5( [ 1 , 4.01 , 9 , 16 , 25 ] ) == [ 1.0 , 3.0 , 4.0 , 5.0 ]

try :
squareRoot_5( [ 1 , 4 , -9 , 16 , 25 ] ) # error at -9
assert False
except ValueError, e :
pass

assert squareRoot_6( squares ) == numbers
assert squareRoot_6( [ 1 , 4 , -9 , 16 , 25 ] ) == None
assert squareRoot_6( [ 1 , 6.25 , 9 , 16 , 25 ] ) == [ 1.0 , 2.5 , 3.0 , 4.0 , 5.0 ]


if __name__ == '__main__' :

testForLoop()


This code creates six different functions for doing basically the same (ie. calculating square root for list of numbers) and then tests differences between them. It presents different forms of for loop construct.

General form of for loop is :
CODE
for element in list_expression :
commands1
[else :
commands2]

Semantics is as follows:

1. For every element in list being result of list_expression perform commands1.
2. If no element is on the list or after the list has been processed perform commands2
3. break statement in commands1 exits the loop without entering else clause.
4. continue statement in commands1 skips rest of commands and gets to the next element (if exists) or to else clause

Code in function testForLoop() should explain all possible cases.

When commands1 actually modify list_expression (case when list_expression is simply l-value) by adding or removing elements, due to internal counter some elements in the list may be omitted from processing or processed more than once. Better clone the list in case like it.

else clause is optional and rarely used in practise.


Other things in code:

1. Header
CODE
#! /usr/bin/env python
# -*- coding: utf-8 -*-

is UNIX specific, it informs the shell how to interpret script. It is not needed in Windows.
Second line shows how to declare text encoding in Python.

2. Keywords
def - declares function
return - returns value, if not present (or not performed) it works as return None
assert - checks if expression (the first one) is True if not throws AssertionError and prints second expression
break & continue - similar to other languages
pass - empty instruction, does nothing, contrary to what one may think - used very frequently
try & except (& finally) - exception handling, we will get there sometime
import - loads module, also in form
QUOTE
from sth import *


3. Code
CODE
if __name__ == '__main__' :
testForLoop()


Explanation:

If this script is being performed as main program then __name__ variable is going to be equal '__main__' (ie. test passes and function performs ), if it is being imported as module then __name__ is NOT equal '__main__' (and test fails, skipping function). It is very convenient way to distinguish between these two cases, it simplifies development and tests of complex applications.

4. Strings

As You can see there are two ways to quote strings: with apostrophe and with quote. It works both for 'ordinary' strings (like '__main__' == "__main__") and for documentation strings ( """Some help""" == '''Some help'''). It is easier to quote the quote character itself, like this: 'She said "Hello" to him' or "She said 'Hello' to him" (watch out, this strings are not equal, contrary to two previous examples).

5. **

... stands for 'power', ie: 2**3 == 8

6. Documentation strings

You can access them in run-time with :

print squareRoot_1.__doc__
print squareRoot_2.__doc__

Observe difference in formatting.

7. Special constants

True is boolean true
False is boolean false
None is sth like null

Remember: first letter is capitalised


PS. I tried to upload the source code but all I got was "Upload failed. You are not permitted to upload this type of file". ??

 

 

 


Reply

marekdudek
Hello

Second part of tutorial presents while loop and conditional language constructs.

Whole code:
CODE

#! /usr/bin/env python
# -*- coding: utf-8 -*-

import math
import sys
import cmath

# -----------------------------------------------------------

def factorial( i ) :

assert i >= 0

if i == 0 :
return 1
else :
return i * factorial( i-1 )

# -----------------------------------------------------------

def estimate( number , precision = 0.01 ) :

"""Estimates square root of a number with given precision"""

def avg( a , b ) :
return ( a + b ) / 2.0

min , max = 0 , number

while True :
est = avg( max , min )
diff = ( est * est ) - number
if math.fabs( diff ) <= precision :
return est
else :
if diff > 0 :
max = est
else :
min = est

# -----------------------------------------------------------

def sqrtList( lst , allowNegative = False , allowComplex = False ) :

if allowComplex :
allowNegative = True
result = []
while not len( lst ) == 0 :
number , lst = lst[ 0 ] , lst[ 1: ]
root = None
if number > 0 :
root = math.sqrt( number )
else:
if not allowNegative :
break
else :
if allowComplex :
root = cmath.sqrt( number)
result.append( root )
else :
return result

# -----------------------------------------------------------

def factorials( n ) :

print '%s %10s' % ( 'i' , 'fac' )
print 12 * '-'
for i in range( n ) :
print '%s %10s' % ( i , factorial( i ) )

# -----------------------------------------------------------

def swap() :

a = 2
b = 3
a , b = b , a
assert a == 3 and b == 2
# -----------------------------------------------------------

def absList( lst ) :

result = []
for el in lst:
if el > 0 :
abs = 1
elif el == 0 :
abs = 0
else :
abs = -1
result.append( abs )
return result

# -----------------------------------------------------------

def bigFactorial( n ) :

print 'Recursion limit: %d, setting to %d' % ( sys.getrecursionlimit() , n+3 )
sys.setrecursionlimit( n + 3 )

f = factorial( n )
print 'Factorial of %d has %d digits:\n%d' % ( n , len( str( f ) ) , f )

# -----------------------------------------------------------

def conditionalExpression() :

a = 2
b = 4

cond = True

c = a if cond else b
assert c == a

cond = False

c = a if cond else b
assert c == b
# -----------------------------------------------------------

def slices() :

a , b , c , d , e = 1 , 2 , 3 , 4 , 5
assert a == 1 and b == 2 and c == 3 and d == 4 and e == 5

#
# indexes = 0 1 2 3 4
lst = [ a , b , c , d , e ]

assert lst[0] == a and lst[4] == e

assert lst[0:3] == [ a , b , c ]
assert lst[1:3] == [ b , c ]
assert lst[ :3] == [ a , b , c ]

assert lst[2:4] == [ c , d ]
assert lst[2:5] == [ c , d , e ]
assert lst[2: ] == [ c , d , e ]


if __name__ == '__main__' :

factorials( 10 )

print

number = 25
precision = 0.0001
print 'Estimated (prec. %f) square root of %d is %f' % ( precision , number , estimate( number , precision ) )

print

swap()

print

bigFactorial( 1024 )

print

lst = [ 1 , 4 , -9 , 16 , 25 ]

print 'List is :' , lst
print 'Square list is:' , sqrtList( lst )
print 'Square list is:' , sqrtList( lst , allowNegative = True )
print 'Square list is:' , sqrtList( lst , True )
print 'Square list is:' , sqrtList( lst , allowComplex = True )
print 'Square list is:' , sqrtList( lst , False , True )
print 'Square list is:' , sqrtList( lst , True , True )
assert sqrtList( lst , allowComplex = True ) == [1.0, 2.0, 3j, 4.0, 5.0]

lst = [ 0 , 4 , -9 , 16 , 25 ]
print 'List is :' , lst
print 'Abs list is:' , absList( lst )
print

conditionalExpression()

slices()

... and step by step:

while loop

Typical use of while loop:
CODE
def estimate( number , precision = 0.01 ) :
"""Estimates square root of a number with given precision"""
def avg( a , b ) :
return ( a + b ) / 2.0
min , max = 0 , number # simultaneous assignment
while True :
est = avg( max , min )
diff = ( est * est ) - number
if math.fabs( diff ) <= precision :
return est
else :
if diff > 0 :
max = est
else :
min = est

... and use with else clause
CODE

def sqrtList( lst , allowNegative = False , allowComplex = False ) :
if allowComplex :
allowNegative = True
result = []
while not len( lst ) == 0 :
number , lst = lst[0] , lst[1:] # simultaneous assignment and slice
root = None
if number > 0 :
root = math.sqrt( number )
else:
if not allowNegative :
break
else :
if allowComplex :
root = cmath.sqrt( number)
result.append( root )
else :
return result


Semantics is similar to for loop. else clause (if present) is executed after condition is no longer satisfied with exception of break statement executed in this loop. continue is not an exception.

Worth of mentioning:
1. Both functions use arguments with default values. There are multiple ways to execute functions like that:
CODE

lst = [ 1 , 4 , -9 , 16 , 25 ]
sqrtList( lst )
sqrtList( lst , allowNegative = True )
sqrtList( lst , True )
sqrtList( lst , allowComplex = True )
sqrtList( lst , False , True )
sqrtList( lst , True , True )
assert sqrtList( lst , allowComplex = True ) == [1.0, 2.0, 3j, 4.0, 5.0]

Simple constraint is that You cannot declare non-default arguments after default argument. Last three lines of previous code snippet present the advantage of naming arguments. (Code is longer in this case but clarity is higher, and imagine ten switches like that).
Argument passing and taking is quite complicated matter, more on this later.
2. You can declare functions INSIDE functions as seen in the first snippet.
3. You can make simultaneous assignments, works with any number of pairs:
CODE

a , b , c , d , e = 1 , 2 , 3 , 4 , 5
assert a == 1 and b == 2 and c == 3 and d == 4 and e == 5

Assignments are really simultaneous:
CODE

def swap() :

a = 2
b = 3
a , b = b , a
assert a == 3 and b == 2


4. Slices:
You can access sublists of a list with slice notation. Simplest form is:
CODE
#
        #        indexes =   0   1   2   3   4
        lst              = [ a , b , c , d , e ]

        assert lst[0] == a and lst[4] == e

        assert lst[0:3] == [ a , b , c         ]
        assert lst[1:3] == [     b , c         ]
        assert lst[ :3] == [ a , b , c         ]

        assert lst[2:4] == [         c , d     ]
        assert lst[2:5] == [         c , d , e ]
        assert lst[2: ] == [         c , d , e ]

... more complicated form involves negative and "too big" indexes. We'll get there.

5. Complex numbers, You declare them as:
CODE
c = 2 + 3j

... and standard numeric functions are in cmath instead of math.

Recursion

Recursion in Python brings no surprises :
CODE

def factorial( i ) :
if i == 0 :
return 1
else :
return i * factorial( i-1 )


Conditionals

if statement in full form:
CODE

def absList( lst ) :
result = []
for el in lst:
if el > 0 :
abs = 1
elif el == 0 :
abs = 0
else :
abs = -1
result.append( abs )
return result

Multiple elifs are possible.
There is no case nor switch statements in Python. Conditions are evaluated from top to bottom, statements after the first true one are executed, there is no fall-through logic.

Conditional expression

CODE

a = cond ? b : c // That would be in Java
a = b if cond else c # That's in Python


... looks somewhat strange but instead it has been chosen from among many after Serious Considerations smile.gif

That's all for now, bye

Marek

 

 

 


Reply

marekdudek
Hello again

Third part of tutorial presents very useful feature called list comprehension.

Whole code:


CODE
#! /usr/bin/env python
# -*- coding: utf-8 -*-

import math
import cmath
import types

# ---------------------------------------------------------------------------

def squareList1( lst ) :

result = []
for el in lst :
result.append( math.sqrt( el ) )
return result

def squareList2( lst ) :

result = [ math.sqrt( el ) for el in lst ]
return result

def squareList3( lst ) :

return [ math.sqrt( el ) for el in lst ]


def squareList4( lst ) :

return [ math.sqrt( el ) if el >= 0 else cmath.sqrt( el ) for el in lst ]

# ---------------------------------------------------------------------------

def listComprehension() :

l = [ 1, 4, 9, 16, 25 ]

assert type( l ) == types.ListType

assert squareList1( l ) == squareList2( l )
assert squareList1( l ) == squareList3( l )
assert squareList2( l ) == squareList3( l )

l = [ 1, 4, -9, 16, 25 ]
assert squareList4( l ) == [1.0, 2.0, 3j, 4.0, 5.0]

# ---------------------------------------------------------------------------

def tupleComprehension():

t = ( 1, 4, 9, 16, 25 )

assert type( t ) == types.TupleType
assert squareList3( t ) == [1.0, 2.0, 3.0, 4.0, 5.0]
assert type( squareList3( t ) ) == types.ListType

# ---------------------------------------------------------------------------

def dictComprehension() :

d = { 1: 'one', 2: 'two', 3: 'three' }

assert type( d ) == types.DictType

assert [ str( v ) + str( k ) for k, v in d.items() ] == [ 'one1', 'two2', 'three3' ]
assert [ k for k in d ] == [ 1, 2, 3 ]
assert [ k for k in d.keys() ] == [ 1, 2, 3 ]
assert [ v for v in d.values() ] == [ 'one', 'two', 'three' ]

# ---------------------------------------------------------------------------

def conditionalComprehension() :

l = range( 5 )
assert l == [ 0, 1, 2, 3, 4 ]

evens = [ el for el in l if el % 2 == 0 ]
odds = [ el for el in l if el % 2 <> 0 ]
assert evens == [ 0, 2, 4 ]
assert odds == [ 1, 3 ]

# ---------------------------------------------------------------------------

def complexComprehensions() :

l = range( 5 )
assert l == [ 0, 1, 2, 3, 4 ]

l2 = [ el + len( l ) for el in l if l[el] % 2 == 0 ]
assert l2 == [ 5, 7, 9 ]

a = 0.5
l3 = [ el + a for el in l ]
assert l3 == [ 0.5, 1.5, 2.5, 3.5, 4.5 ]


l4 = [ [ el, 3*el ] for el in l ]
assert l4 == [[0, 0], [1, 3], [2, 6], [3, 9], [4, 12]]

t5 = [ ( el, 3*el ) for el in l ]
assert t5 == [(0, 0), (1, 3), (2, 6), (3, 9), (4, 12)]

d6 = [ { el : 3*el } for el in l ]
assert d6 == [{0: 0}, {1: 3}, {2: 6}, {3: 9}, {4: 12}]

# ---------------------------------------------------------------------------

def multipleListComprehensions() :

l1 = [ 0, 1 ]
l2 = [ 2, 3 ]
l3 = [ 4, 5 ]
l4 = [ 6, 7 ]

assert [ ( e1, e2 ) for e1 in l1 for e2 in l2 ] == [ (0, 2),
(0, 3),
(1, 2),
(1, 3) ]

assert [ ( e1, e2, e3 ) for e1 in l1 for e2 in l2 for e3 in l3 ] == [ (0, 2, 4),
(0, 2, 5),
(0, 3, 4),
(0, 3, 5),
(1, 2, 4),
(1, 2, 5),
(1, 3, 4),
(1, 3, 5) ]


assert [ ( e1, e2, e3, e4 ) for e1 in l1 for e2 in l2 for e3 in l3 for e4 in l4 ] == [ (0, 2, 4, 6),
(0, 2, 4, 7),
(0, 2, 5, 6),
(0, 2, 5, 7),
(0, 3, 4, 6),
(0, 3, 4, 7),
(0, 3, 5, 6),
(0, 3, 5, 7),
(1, 2, 4, 6),
(1, 2, 4, 7),
(1, 2, 5, 6),
(1, 2, 5, 7),
(1, 3, 4, 6),
(1, 3, 4, 7),
(1, 3, 5, 6),
(1, 3, 5, 7) ]

def xor( b1 , b2, b3 ) :
"""Exclusive 'or'

True if and only if exactly one of arguments is true
"""

return ( b1 and not (b2 or b3) ) or \
( b2 and not (b1 or b3) ) or \
( b3 and not (b1 or b2) )

b = [ False, True ]

assert [ ( b1, b2, b3 ) for b1 in b
for b2 in b
for b3 in b
if xor( b1, b2, b3 ) ] == [ (False, False, True),
(False, True, False),
(True, False, False) ]

# ---------------------------------------------------------------------------

if __name__ == '__main__' :

listComprehension()
tupleComprehension()
dictComprehension()
conditionalComprehension()
complexComprehensions()
multipleListComprehensions()



Earlier we used to process list using loop constructs. While it can be done that way in most cases more elegant and efficient way exists: list comprehension. Simplest form looks like this:
CODE
[ expression for variable in list ]


and as a result produces a list. It is equivalent for:
CODE
result = []
for el in list :
        result.append( expression( el ) )
return result


Lets see how example from the first post evolve:
CODE
def squareList1( lst ) :
result = []
for el in lst :
result.append( math.sqrt( el ) )
return result

def squareList2( lst ) :
result = [ math.sqrt( el ) for el in lst ]
return result

def squareList3( lst ) :
return [ math.sqrt( el ) for el in lst ]

def listComprehension() :
l = [ 1, 4, 9, 16, 25 ]
assert type( l ) == types.ListType
assert squareList1( l ) == squareList2( l )
assert squareList1( l ) == squareList3( l )
assert squareList2( l ) == squareList3( l )


List comprehension can have conditional clause, example:
CODE
def conditionalComprehension() :
l = range( 5 )
assert l == [ 0, 1, 2, 3, 4 ]
evens = [ el for el in l if el % 2 == 0 ]
odds = [ el for el in l if el % 2 <> 0 ]
assert evens == [ 0, 2, 4 ]
assert odds == [ 1, 3 ]


While list comprehension always produces result of type list it can process other iterable Python types ie. tuples and dictionaries (and types derived from them). Tuple is an immutable list and dictionary works as associative memory (map). Lets see how to process them using list comprehension:

CODE

t = ( 1, 4, 9, 16, 25 )
assert squareList3( t ) == [1.0, 2.0, 3.0, 4.0, 5.0]

d = { 1: 'one', 2: 'two', 3: 'three' }
assert [ str( v ) + str( k ) for k, v in d.items() ] == [ 'one1', 'two2', 'three3' ] # 6
assert [ k for k in d ] == [ 1, 2, 3 ] # 7
assert [ k for k in d.keys() ] == [ 1, 2, 3 ] # 8
assert [ v for v in d.values() ] == [ 'one', 'two', 'three' ] # 9


Tuple (You initialize it like a list but using round parentheses) is processed exactly like a list (pay attention that it can be passed to a function that we wrote for a list). Things get more complicated when dictionary is involved. Using only dictionary reference (like #7) causes only keys of dictionary being process, #8 proves it. If You want to process also values use items() method. Notice that You get two variables for every key-value pair in dictionary. To process only values use values().

Multiple list comprehension:
You can process multiple list in one expression, in this case You get to process all combinations.
CODE
[ ( e1, e2 ) for e1 in lst1 for e2 in lst2 ]

is equivalent for
CODE
result = []
for e1 in lst1 :
        for e2 in lst2 :
                result.append( (e1, e2) )
return result


Example:
CODE

l1 = [ 0, 1 ]
l2 = [ 2, 3 ]
assert [ ( e1, e2 ) for e1 in l1 for e2 in l2 ] == [ (0, 2),
(0, 3),
(1, 2),
(1, 3) ]


and another:
CODE

def xor( b1 , b2, b3 ) :
"""Exclusive 'or'
True if and only if exactly one of arguments is true
"""
return ( b1 and not (b2 or b3) ) or \
( b2 and not (b1 or b3) ) or \
( b3 and not (b1 or b2) )

b = [ False, True ]
assert [ ( b1, b2, b3 ) for b1 in b for b2 in b for b3 in b if xor( b1, b2, b3 ) ] == [ (False, False, True),
(False, True, False),
(True, False, False) ]


List comprehension is a powerful technique, it belongs to set of functional programming concepts available in Python. Together with them it is one of reasons for Python's well-earned fame.
--------------------------------

1. Function type() gets type of object. Constants available in types module.
2. Function range() generates list with arithmetic progression, based on start (default=0), stop and step (default=1) arguments:
CODE
assert range( 5 )          == [ 0, 1, 2, 3, 4 ]
assert range( 5 , 10 )     ==                [ 5, 6, 7, 8, 9 ]
assert range( 5 , 10 , 2 ) ==                [ 5,    7,    9 ]

As You can see stop value is never included.

Bye, see You around

Reply

marekdudek
Hello again

Fourth lesson concerns functional programming capabilities embedded with Python. Whole code is:
CODE

#! /usr/bin/env python
# -*- coding: utf-8 -*-

import random

# ---------------------------------------------------------------------------

def lambdaCalculus() :

f1 = lambda x: x + 2
lst = range( 5 )

assert lst == [ 0, 1, 2, 3, 4 ]
assert [ f1(x) for x in lst ] == [ 2, 3, 4, 5, 6 ]

f2 = lambda x: f1(x)

assert f2( 3 ) == 5

factorial = lambda n: n * factorial( n - 1 ) if n > 0 else 1

f = [ factorial( i ) for i in range( 6 ) ]
assert f == [ 1, 1, 2, 6, 24, 120 ]

identity = lambda x: x

max = 100
for i in range( max ) :
n = random.randint( 1, max * max )
assert n == identity( n )

sum = lambda x,y: x+y
assert sum( 2, 3 ) == 5

# ---------------------------------------------------------------------------

def functionals() :

lst = range( 1, 11 )

# 'map' function
def f1(x) :
return x*2
def f2(x) :
return x**2
def f3(x) :
return x**3

assert lst == [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
assert map( f1, lst ) == map( lambda x: 2*x , lst ) == [ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 ]
assert map( f2, lst ) == map( lambda x: x**2, lst ) == [ 1, 4, 9, 16, 25, 36, 49, 64, 81, 100 ]
assert map( f3, lst ) == map( lambda x: x**3, lst ) == [ 1, 8, 27, 64, 125, 216, 343, 512, 729, 1000 ]

def f(x, y) :
return x+y
lst2 = [ x*2 for x in lst ]
assert map( f, lst, lst2 ) == [3, 6, 9, 12, 15, 18, 21, 24, 27, 30 ]

# 'filter' function

def even(x) :
return x%2==0
def odd(x) :
return x%2<>0

assert filter( even, lst ) == filter( lambda x: x%2==0, lst ) == [2, 4, 6, 8, 10]
assert filter( odd , lst ) == filter( lambda x: x%2<>0, lst ) == [1, 3, 5, 7, 9 ]

# 'reduce' function

lst = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
assert reduce( lambda x,y: x+y , lst ) == 55

# another way to calculate factorial
def factorial( n ) :
return reduce( lambda x,y: x*y, range(1, n+1), 1 )
assert factorial( 0 ) == 1
assert factorial( 1 ) == 1
assert factorial( 2 ) == 2
assert factorial( 3 ) == 6
assert factorial( 4 ) == 24
assert factorial( 5 ) == 120

def sum( x, y ) :
return x+y
assert reduce( sum, [1, 2, 3] ) == 6
assert reduce( sum, [1, 2 ] ) == 3
assert reduce( sum, [1 ] ) == 1


# ---------------------------------------------------------------------------
def usefulFunctions() :

# 'enumerate'

fun = lambda x: x*2+2
X = map( fun, range( 11 ) )

print 'index value'
print '-----------'
for index, x in enumerate( X ) :
print '%5d %5d' % (index, x)

assert [ (x, index) for x, index in enumerate( X ) ] == [ (0, 2), (1, 4), (2, 6), (3, 8), (4, 10), (5, 12),
(6, 14), (7, 16), (8, 18), (9, 20), (10, 22) ]

D = { 'one':1, 'two':2, 'three':3 }

print 'index key'
print '-----------'
for index, k in enumerate( D ) :
print '%5d %5s' % (index, k )

print 'index key value'
print '-----------------'
for index, (k, v) in enumerate( D.items() ) :
print '%5d %5s %5d' % (index, k, v )

# 'zip'
fun = lambda x: x**2
X = range( 5, 11 )
Y = map( fun, X )

print 'arg value'
print '---------'
for x, y in zip( X, Y ) :
print '%3d %5d' % (x, y)

Z = map( lambda x: x**3, X )
print 'arg value value'
print '---------------'
for x, y, z in zip( X, Y, Z ) :
print '%3d %5d %5d' % (x, y, z)

# ---------------------------------------------------------------------------

def unpacking() :

a, b, c = 1, 2, 3
( a, b, c ) = ( 1, 2, 3 )

X = [3, 4, 5]
Y = map( lambda x: x*x, X )

for x, y in zip( X, Y ) :
print '%s %s' % (x, y)

for (x, y) in zip( X, Y ) :
print x, y

for i, x in enumerate( X ) :
print i, x

for (i, x) in enumerate( X ) :
print i, x

assert [ '%s %s' % (x, y) for x, y in zip( X, Y ) ] == ['3 9', '4 16', '5 25']
assert [ '%s %s' % (x, y) for (x, y) in zip( X, Y ) ] == ['3 9', '4 16', '5 25']

try :
( a, b, c ) = ( 1, 2 )
assert False
except ValueError, ve :
assert str(ve) == 'need more than 2 values to unpack'

try :
( a, b ) = ( 1, 2, 3 )
assert False
except ValueError, ve :
assert str(ve) == 'too many values to unpack'

a, b = 1, (2, 3)
c, d = b
assert a == 1 and c == 2 and d == 3

a, (c, d) = 1, (2, 3)
assert a == 1 and c == 2 and d == 3


# ---------------------------------------------------------------------------

if __name__ == '__main__' :

lambdaCalculus()
functionals()
usefulFunctions()
unpacking()



Let's look closer.

Lambda functions
Very useful is possibility to create lambda functions (based on lambda calculus theoretical notation). General for is
CODE
lambda arguments: expression

which is equivalent to
CODE
def name(arguments):
    return expression

Examples of declaration:
CODE

f1 = lambda x: x + 2
lst = range( 5 )

assert lst == [ 0, 1, 2, 3, 4 ]
assert [ f1(x) for x in lst ] == [ 2, 3, 4, 5, 6 ]

Example with two arguments:
CODE

sum = lambda x,y: x+y
assert sum( 2, 3 ) == 5

Lambda function can use names from outside of it's scope:
CODE

f2 = lambda x: f1(x)

assert f2( 3 ) == 5

Lambda function may evaluate to a reference:
CODE

identity = lambda x: x

max = 100
for i in range( max ) :
n = random.randint( 1, max * max )
assert n == identity( n )

Lambda functions can be recursive:
CODE

factorial = lambda n: n * factorial( n - 1 ) if n > 0 else 1

f = [ factorial( i ) for i in range( 6 ) ]
assert f == [ 1, 1, 2, 6, 24, 120 ]

While You can name and reuse lambda function they are very often used as anonymous functions, ie. defined exactly (inline) where they're used, we'll see examples further.

Functionals
There are three functions in Python that behave like functionals. They are map(), filter() and reduce(). Let's see their usage.
map() accepts function and collection and creates list of results of applying a function to elements of collection
CODE

lst = range( 1, 11 )
def f1(x) :
return x*2
def f2(x) :
return x**2
def f3(x) :
return x**3
assert lst == [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
assert map( f1, lst ) == map( lambda x: 2*x , lst ) == [ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 ]
assert map( f2, lst ) == map( lambda x: x**2, lst ) == [ 1, 4, 9, 16, 25, 36, 49, 64, 81, 100 ]
assert map( f3, lst ) == map( lambda x: x**3, lst ) == [ 1, 8, 27, 64, 125, 216, 343, 512, 729, 1000 ]

(note anonymous function usage). More than one collection can be passed. In this case result of map() is a list of results of calling a function of multiple arguments (as many as collections). Function must accept multiple arguments.
CODE

def f(x, y) :
return x+y
lst2 = [ x*2 for x in lst ]
assert map( f, lst, lst2 ) == [3, 6, 9, 12, 15, 18, 21, 24, 27, 30 ]


filter() accepts function (a predicate) and collection returning as a result a list of elements from collection that the predicate evaluates to True:
CODE

def even(x) :
return x%2==0
def odd(x) :
return x%2<>0
assert filter( even, lst ) == filter( lambda x: x%2==0, lst ) == [2, 4, 6, 8, 10]
assert filter( odd , lst ) == filter( lambda x: x%2<>0, lst ) == [1, 3, 5, 7, 9 ]

reduce() accepts (binary, ie. two-argument) function and collection and returns single value. This value is a result of applying function to 1st and 2nd elements and then the result to 3rd, 4th and so on (or simply the only element if collection's length is 1):
CODE

lst = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
assert reduce( lambda x,y: x+y , lst ) == 55
def sum( x, y ) :
return x+y
assert reduce( sum, [1, 2, 3] ) == 6
assert reduce( sum, [1, 2 ] ) == 3
assert reduce( sum, [1 ] ) == 1

reduce() may accept additional third value that is returned in special case when passed collection is empty. We will use it to define factorial once more:
CODE

def factorial( n ) :
return reduce( lambda x,y: x*y, range(1, n+1), 1 )
assert factorial( 0 ) == 1
assert factorial( 1 ) == 1
assert factorial( 2 ) == 2
assert factorial( 3 ) == 6
assert factorial( 4 ) == 24
assert factorial( 5 ) == 120


Other functions useful for collection processing

enumerate(lst) is useful to iterate over list and it's indexes, example of usage:
CODE

fun = lambda x: x*2+2
X = map( fun, range( 11 ) )
for index, x in enumerate( X ) :
print '%5d %5d' % (index, x)

More formally: enumerate() function returns enumerate object whose next() method returns tuple containing index and element of iterated-over collection. In example above next() method is not explicitly called, for loop calls it behind the scenes. Also during list comprehension, by the way:
CODE

assert [ (x, index) for x, index in enumerate( X ) ] == [ (0, 2), (1, 4), (2, 6), (3, 8), (4, 10), (5, 12),
(6, 14), (7, 16), (8, 18), (9, 20), (10, 22) ]


Enumerating a dictionary:
CODE

D = { 'one':1, 'two':2, 'three':3 }
for index, k in enumerate( D ) :
print '%5d %5s' % (index, k )
for index, (k, v) in enumerate( D.items() ) :
print '%5d %5s %5d' % (index, k, v )

As in "dictionary" comprehension, simple dictionary reference iterates over keys only (first usage above). To iterate over key-value pair use items() method (second usage).

zip( col1, col2 , ...) returns list of tuples so that first tuple contains first element from col1 and col2 (and col3 ...), second tuple contains second element from col1 and col2 (and col3 ...) and so on:
CODE

fun = lambda x: x**2
X = range( 5, 11 )
Y = map( fun, X )
for x, y in zip( X, Y ) :
print '%3d %5d' % (x, y)
Z = map( lambda x: x**3, X )
for x, y, z in zip( X, Y, Z ) :
print '%3d %5d %5d' % (x, y, z)


Unpacking:
Explanation of mechanism that we used before without knowing it exists: whenever we use comma notation in constructs like:
CODE

X = [3, 4, 5]
Y = map( lambda x: x*x, X )
a, b, c = 1, 2, 3
for i, x in enumerate( X ) :
print i, x
assert [ '%s %s' % (x, y) for x, y in zip( X, Y ) ] == ['3 9', '4 16', '5 25']

in reality we operate on (implicitly created) tuple(s), omiting parentheses is only a shorthand. Above statements are equivalent to
CODE

( a, b, c ) = 1, 2, 3
for (i, x) in enumerate( X ) :
print i, x
assert [ '%s %s' % (x, y) for (x, y) in zip( X, Y ) ] == ['3 9', '4 16', '5 25']

The process of matching values from result tuple to corresponding references of newly created tuple is called unpacking. (Expression in green also implicitly creates tuple contrary to comma separated arguments to print statement. Of course no unpacking is involved).
Since Python allows us to construct functions and expressions that may generally return tuples of unknown length we may encounter (and handle) run-time error during unpacking:
CODE

try :
( a, b, c ) = ( 1, 2 )
assert False
except ValueError, ve :
assert str(ve) == 'need more than 2 values to unpack'

try :
( a, b ) = ( 1, 2, 3 )
assert False
except ValueError, ve :
assert str(ve) == 'too many values to unpack'

More complicated unpacking is involved when collection being unpacked is nested:
CODE

a, b = 1, (2, 3)
c, d = b
assert a == 1 and c == 2 and d == 3
a, (c, d) = 1, (2, 3)
assert a == 1 and c == 2 and d == 3

This last code snippet at last explains notation while enumerating over items of dictionary:
CODE

for index, (k, v) in enumerate( D.items() ) :
print '%5d %5s %5d' % (index, k, v )


That's all for now. Exception handling in next part.
Happy New Year to everybody

Reply



Got an Opinion! Express your Views! (no registration):-
Add your Reply/ Opinion/ Views/ Comments/ Suggestion/ Questions/ Queries etc.
Posts with decent grammar & English will be accepted and please refrain from profanities.
For asking a Question, We recommend you to sign-up (for free) so that you can track the topic easily.

Nature of your Post*: Opinion/ Reply/ Comments
Question/Query
Feedback to us.
       
Name   Email
Title/Question*

(Maximum characters: 10,000)
You have characters left.
Confirm Code:

Similar Topics

Keywords : python, manace, control, flow, python

  1. Python
    (1)
  2. Python
    another programming language (8)
    There are so many languages used in software and web development. Python is one of them. Basically
    Python is object-oriented , high-level programming language with dynamic semantics. Python was
    developed in the 90’s. Python is simple and easy to learn. Therefore it reduces cost of program
    maintenance. It is very attractive for rapid application development because of its high-level
    built-in data structures, combined with dynamic typing and dynamic binding. Python is also use as a
    scripting or glue language to connect existing components. Python supports modules and ....
  3. [pygame] Python Game
    (4)
    On this tutorial we will see how to draw a circle on the screen and move it around using the arrows
    of the keyboard. (Don't worry if you don't get anything, the code will be analysed line by
    line) CODE #!/usr/bin/env python import pygame from pygame.locals import * if not
    pygame.font:     print 'Atention, there are no fonts.' if not pygame.mixer:
        print 'Atention, there is no sound.' pygame.init() red = (255, 0,
    0) black = (0, 0, 0) window_width = 640 window_height = 480 window = pygame....
  4. Python
    Programming Language (4)
    Does anybody else know any python? I've started learning it, because I heard somewhere that it
    is quite easy to learn and I want to learn a programming language quickly /smile.gif"
    style="vertical-align:middle" emoid=":)" border="0" alt="smile.gif" />. I haven't learned how
    to do any complex stuff with it yet, but its still fun learning about it /smile.gif"
    style="vertical-align:middle" emoid=":)" border="0" alt="smile.gif" />. If you want to find out
    more info about Python, then you can go to their website. I'm not sure if i'm allowed to
    post links....
  5. Password Generator
    Made in Python (9)
    This is a Password Genorator i made in python use Tkinter as the GUI. I will Compile it soon so
    people with out Python can use it. here is the source code CODE import random, math from
    Tkinter import * root=Tk() root.title("PassGen") length = Label(root,
    text="password length:") length.pack() input = Entry(root,
    text="8") input.pack() input.insert(0, "8") units =
    "abcdefghijkmnopqrstuvwxyz0123456789" password = Label(root,
    text="password:") pas....
  6. Fib Gen In Python
    (1)
    OK this is one of my first programs.. from Tkinter import * CODE def NextNumber():
        count = 0     x = 0     y = 1     while count <= int(Range.get()):
            for item in [x]:             listbox.insert(0, item)         z = x
            x = z + y         y = z         count = count + 1 root = Tk() Title =
    Label(root, text = "Calculate fib number:") Title.pack() Range =
    Entry(root) Range.pack() PrintNextNumber = Button(root, text = "   Display  
    ", ....
  7. Delicious + Gmail
    python (2)
    I stumbled upon this link earlier today and was hoping someone could explain or walk me through
    getting the script running. http://ponderer.org/del.icio.us I'll keep the post short since I
    have no clue as to what I should. I'll just say that I rarely work on WinXP and I would rather
    get it running on my old win box sitting in the corner. ....
  8. Need Help With My Python Programs
    just extremely basic stuff (11)
    ok, i am learning python, and i realy dont know much. my guide im using said to make a program
    where it asks your name, and if the name is yours your make it so there is a compliment, if it is
    another name you make it that its an insult, and anything else makes it say Nice name. here is what
    i wrote name = raw_input("What is your name?") if name == John: print "Your name is freaking
    sweet, you must be a god or something." elif name == Bob: print "You have a freakin' weird
    name, dude." else: print "Nice name,",name i donot understand what i am doing w....
  9. Ok, So I'm Learning Python...
    (3)
    I was wondering, can I make games in python, even simple text based ones? me and my friend wanted to
    start making homebrew games, and we decided to start out learning python. I've learned a bit,
    not much, but enought to make one of those conversations with the computer, like with loops and
    where they ask questions like "what is your name?" and then say it back etc. We plan on also
    learning C++, which we will learn later after we get real good with Python. However, will I
    eventually be able to make games with Python?....

    1. Looking for python, manace, control, flow, python

Searching Video's for python, manace, control, flow, python
advertisement



Python Manace: Control Flow I - python tutorial



 

 

 

 

ADD REPLY / Got an Opinion! Remove these ADs! RAPID SEARCH! Free Web Hosting [X]
Express your Opinions, Thoughts or Contribute more info. to help others.
Ask your Doubts & Queries to get answers, So that "Together We can help others!"
Register FREE for AD-FREE forum, Create your own topics, Ask Questions, track topics, setup subscriptions & notifications and Get a Free Website w/ Email and FTP.
500MB Space *No Ads*, CPanel, FTP, PHP, MySQL, EMails - 100% FREE