It's said that you can write C in any programming language. I used to do this all the time – C was my first language, and I came to Python from Perl – but I am doing it much less these days and profiting from the change. Look at how I was parsing 2D GeoRSS coordinates or a GML posList into tuples back in 2005 in the 6 lines below.
# value is "33.338611 52.566592 32.537546 52.527238 31.744196 52.409555" latlons = value.split() coords =  for i in range(0, len(latlons), 2): lat = float(latlons[i]) lon = float(latlons[i+1]) coords.append((lon, lat)) # coords is [(52.566592, 33.338611), ...]
Counters, increments, offsets – It's rudimentary C pointer arithmetic in Python. I recently rewrote this in a different style.
def take_tuples(itr): nxt = itr.next while True: lat = nxt() lon = nxt() yield lon, lat latlons = iter(map(float, text.split())) coords = list(take_tuples(latlons))
Python isn't a functional language, but I still enjoy and benefit from using it in a functional style. The statements in my first, older batch of code are concerned with how to extract coordinate pairs. The statements in the second express what values I want. I want the results of float mapped over all the items split from the initial value, and then I want a list of pairs of these results.
For a more simple example, If what I want is a list of integers from 1 to 10, I write this:
instead of this:
And if what I want is integers converted to floats, I write this:
instead of this:
The generator function take_tuples (code section 2, above) is also written in terms of what results I want. It calls next twice on an iterator and yields the pair, swapped. When it hits the end of the iterator, it raises StopIteration. This is expected and normal for functions that accept iterators, like list(). It's the what-not-how way to get things from a sequence, pairwise.
>>> def take_pairs(value): ... itr = iter(value) ... while True: ... yield itr.next(), itr.next() ... >>> list(take_pairs(range(4))) [(0, 1), (2, 3)] >>> list(take_pairs("abc")) [('a', 'b')]
Now, here's the icing: my new code (section 2 above, with map and list and the generator) benchmarks 10% faster than my old C style code. Binding the itr.next to a local variable (nxt) makes a big difference. I'm eating my cake and having it, too.