Per Erik Strandberg /cv /kurser /blog

I am starting to become more and more interested in Faster Python - so here I'll try to list some findings.

List comprehension

A list comprehension is a way of making a new list based on another list. Without list comprehensions an example like this would not be unusual:

    def my_odd_numbers(nums):
        data = list()
        for n in nums:
        return data

    numbers = [4, 5, 6, 7, 8]
    odds1 = my_odd_numbers(numbers)
    print odds1

Contrast the above 5-line function to the equivalent one-liner below:

    odds2 = [2*x+1 for x in numbers]
    print odds2

You can also add conditions to the expression:

    # prints [9, 13, 15, 17]
    print [2*x+1 for x in xrange(4,9) if (x+2)%3 == 0 or x%2 == 0]

And by rearranging the parts an else can be added:

    print [2*x+1 if (x+2)%3 == 0 or x%2 == 0 else -1 for x in xrange(4,9)]
    [9, -1, 13, 15, 17]

So to summarize the syntax is based on x if condition else y or [x if condition else y for z in the_list]

See more in Wikipedia: [1] and in stack overflow [2]

The annoying 'Lambda'

At first I saw the lambda expression as a lay way of ignoring the "return tmp" line so often seen in methods. And possibly a meaningless way of obfuscating the code. See this example where the both methods do the same thing (and print 81):

    def my_first_cube(x): return x**2
    print my_first_cube(9)
    my_lambda_cube = lambda x : x**2
    print my_lambda_cube(9)

But it can also be a used to make a function factory. In the next example I have a function that returns another function based on the parameters sent to the first:

    def my_first_power(n): return lambda x : x ** n
    p5 = my_first_power(5)
    print p5(2), 2 ** 5 

or if you are really into the lambda stuff:

    my_lambda_power = lambda n : (lambda x : x ** n)
    p4 = my_lambda_power(4)
    print p4(3),  3**4

See also [3] .

Functions are first class citizens

A function can be an object, passed into another function, put in lists and so on. In this first example we just create some functions:

    my_add = lambda x : x + 2
    my_div = lambda x : x / 2
    print my_add(8), my_div(84)

Here we use the functions as arguments in a function factory - the example prints 5:

    h = lambda f, g: ( lambda x : g(f(x)) )
    print h(my_add, my_div)(8)

Here we put the functions in a list and call them with the argument 40 - so the print out is a new list containing the values 42 and 20.

    my_funcs = [my_add, my_div]
    print [func(40) for func in my_funcs]

See also wikipedia: [4] .

An ugly rot 13

To get things interesting I end with an ugly rot 13 example:

def my_rot13(my_str):
    from string import ascii_uppercase as u, ascii_lowercase as l, join
    input = u+l
    output = u[13:] + u[:13] + l[13:] + l[:13]
    return join([output[input.find(x)] if x in input else x for x in my_str ], "")
s = "the foo was at the bar on 41st Avenue the 13th of December 2010"

print my_rot13(s)
print my_rot13(my_rot13(s))

Expect the output to be

gur sbb jnf ng gur one ba 41fg Nirahr gur 13gu bs Qrprzore 2010
the foo was at the bar on 41st Avenue the 13th of December 2010

Belongs to Kategori Programmering