We're back after a server migration that caused effbot.org to fall over a bit harder than expected. Expect some glitches.

Bits and Pieces of Python

“Man tager om man så hafva kan…”

Creating an Endless Sequence

This example shows a simple and straightforward way to do this, using a custom sequence wrapper. This works in all versions of Python.

Example: creating an endless sequence
class over_and_over_again:
    def __init__(self, seq):
        self.seq = seq
        self.len = len(seq)
    def __getitem__(self, index):
        return self.seq[index % self.len]

# zip stops when the shortest sequence ends
print zip(range(12), over_and_over_again("spam"))

In more recent versions, it’s possible to do the same thing in more “interesting” ways, using iterators and/or generators. More on that later.

Populating a Dictionary Inside a Lambda

In the following example, the “for k, v in x” part represents any function or expression returning a sequence of key/value pairs, where all keys are unique. The goal is to turn this into a dictionary. In 2.2, this is easy. In 2.1, it’s possible to do this on a single line, without help from outside. In earlier versions, it’s probably worth adding a helper function similar to 2.2’s dict factory…

Example: populating a dictionary inside a lambda
# python 2.4 and later
func = lambda x: dict((k, v) for k, v in x)

# python 2.2 and later
func = lambda x: dict([(k, v) for k, v in x])

# python 2.1 and later (this is ugly!)
func = lambda x: ([d for d in [{}], d.setdefault(k, v) for k, v in x])[0][0]

Note that the 2.1 version creates a tuple containing two list comprehensions, and it returns the first item in the first tuple member.

The first one creates an empty dictionary, and binds it to the d variable in a rather roundabout way: while you cannot use ordinary assignments inside a lambda, nothing stops you from using a list comprehesion to do the job for you. Instead of writing:

variable = value

you can simply write:

[variable for variable in [value]]

The list comprehension converts a list with a single value to another list, containing the same value. But as a side effect, it assigns the value to the given variable.

But let’s go back to the lambda. The second list comprehension loops over the key/value pairs. For each pair, it calls the d.setdefault method, which adds the key/value pair to the dictionary d if the key is not already there. Which, assuming that all keys are unique (or that we don’t really care which value to use if they’re not), is good enough for this task.