Composition and Expression
Composition is a way to combine functions. The combination is also called an Expression.
We have already used it. Here is the most complex example we have seen so far:
>>> float(count(cds, 'G') + count(cds, 'C')) / len(cds) 0.54460093896713613
What is happening when this expression is executed? The first thing to say is that it is a mixed expression of operations and function calls. Let's start with the function calls. If a function is called with an argument representing a composed expression, this one is executed first and the result value is passed to the calling function. So the cds variable is evaluated, which returns the value that it refers to. This value is passed to the len function which returns the length of this value. The same happens for the float function. The operation count(cds, 'G') + count(cds, 'C') is evaluated first, and the result is passed as argument to float.
Let's continue with the operations. There is a precedence list, shown in Table 3.1, for all operators, which determines what to execute first if there are no parentheses, otherwise it is the same as for function calls. So, for the operation count(cds, 'G') + count(cds, 'C') the two count functions are executed first on the value of the cds variable and “G” and “C” respectively. And the two counts are added. The result value of the addition is then passed as argument to the float function followed by the division of the results of the two functions float and len. Figure 3.1 shows the decomposition of the expression into its subcomponents. Sub-expressions are evaluated from bottom to top.
Table 3.1. Order of operator evaluation (highest to lowest)
|+x, -x, ~x||Unary operators|
|x ** y||Power (right associative)|
|x * y, x / y,x % y||Multiplication, division, modulo|
|x + y, x - y||Addition, subtraction|
|x << y, x >> y||Bit shifting|
|x & y||Bitwise and|
|x | y||Bitwise or|
|x < y, x <= y, x > y, x >= y, x == y, x != y, x <> y, x is y, x is not y, x in s, x not in s<||Comparison, identity, sequence membership tests|
|not x||Logical negation|
|x and y||Logical and|
|lambda args: expr||Anonymous function|
So, as in mathematics, the innermost function or operation is evaluated first and the result is passed as argument to the enclosing function or operation. It is important to notice that variables are evaluated and only their values are passed as argument to the function. We will have a closer look at this when we talk about function definitions in Section 8.1.
Exercise 3.1. Composition
Have a look at this example. Can you explain what happens? If you can't please read this section once again.
>>> from string import * >>> cds = 'ATGAACTGTGC' >>> replace(replace(replace(cds, 'A', 'a'), 'T', 'A'), 'a', 'T')