Archive for November, 2009

Python: slicing with zip


Wherein I feel compelled to write some more on Python code that I find more amusing than clear.

The more I use zip the more I love it. I’m thinking about writing a tutorial on how to (ab-) use zip, but for now just this recent discovery.

Say you have two iterators that each yield a stream of objects, iland and iocean (they could be gridded temperature values, say), and you want to get the first 100 values from each iterator to do some processing, whilst not consuming any more than 100 values. You can’t go list(iland)[:100] because that will consume the entire iland iterator and you’ll never be able to get those values past the 100th again.

You can use itertools (probably my second favourite Python module):

land100 = list(itertools.islice(iland, 100))
ocean100 = list(itertools.islice(iocean, 100))

It seems a shame to mention islice and 100 twice. One could use map with a quick pack and unpack, but this is not clear:

land100,ocean100 = map(lambda i: list(itertools.islice(i, 100)), (iland,iocean))

(a simple form of this, which I do sometimes use, is x,y = map(int, (x,y)))

What about giving some love to zip? It turns out that zip will stop consuming as soon as any argument is exhausted. So

zip(range(100), iland, iocean)

returns a list of 100 triples, each triple having an index (the integer from 0 to 99 from the range() list), a value from the iland iterator, and a value from the iocean iterator. And as soon as the list produced by range(100) is exhausted it stops consuming from iland and iocean, so their subsequent values can be consumed by other parts of the program.

And yes, this seems to work by relying on a rather implementation specific feature of zip that I’m not sure should be set in stone.

That zip form above is all very good if one wants to go for n,land,ocean in ..., but what if we want the 100 land values and 100 ocean values each in their own list (like the code at the beginning of the article)? We can use zip again!

_,land100,ocean100 = zip(*zip(range(100), iland, iocean))

zip(*thing) turns a list of triples into a triple of lists, which is then destructured into the 3 variables _ (a classic dummy), land100, and ocean100.

Don’t worry, the actual code use the islice form from the first box because I think it’s the clearest.

Carbon into Trees


The BBC report that the Forestry Commission want to afforest 4% of the UK. And thereby get us 10% of the way towards our 80% emissions reduction target. Their wording is slightly odd, but see paragraph 12:

It is hoped the latest plan would absorb 10% of the UK’s target of slashing its emissions of greenhouse gases by 80% by 2050.

Alarm bells ringing. 1 million hectares (4% of the UK land) can sequester 8% (10% of an 80% emissions reduction) of the UK’s current CO2 emissions? No. My earlier article on coppicing willow suggests that an optimistic estimate for sequestration is 18 tonnes CO2 per hectare. So with 4% of the UK land, we could sequester 18 million tonnes, or about 3% of our (600 million tonnes of) emissions. I think my 3% figure is a really top end estimate. It’s not like willow grows particularly well in this country (but it is one of the best crops for sequestration) and with 4% of the UK covered, we may have to afforest some sub-optimal sites; short rotation coppicing is also different from growing mature forest, but I have a hard time believing that growing mature forest pulls down more carbon (yeah yeah, soil, nitrogen).

So where do the Forestry Commission get 8% from? I have no idea. And as usual the clueless journalists at the BBC fail to use the power of hyperlinking (welcome to the 1990’s) and they don’t have a link to the Forestry Commission research. Or even their press release (I suppose that would let everyone know they copied their homework).

Oh wait, here’s the first paragraph of the Forestry Commision press release: (ewgh Lotus Notes)

If an extra four per cent of the United Kingdom’s land were planted with new woodland over the next 40 years, it could be locking up ten per cent of the nation’s predicted greenhouse gas emissions by the 2050s.

Oh. So they mean 10% of our 2050 emissions. Which, as you know, are going to be 80% less than our current emissions. So 10% of 20% of our current emissions. Or 2%. Yeah, I buy that (just about, but at least it’s biologically plausible).

So the BBC mangled the press release. Does the BBC version seem very unclear to anyone else?