Pick a column for each row by column-header name I am parsing a table:




    |-------|
    |Bar|Foo|
    |-------|
    | 5 | 6 |
    |'f'|'g'|
    | 1 | 8 |
    |_______|



I've tried a number of ways of writing a pick function in Python:



#!/usr/bin/env python

from collections import OrderedDict


def pick0(r, k):
    Bar, Foo = r
    return locals().get(k)


def pick1(r, k, h):
    try:
        return r[h.index(k)]
    except ValueError:
        return None


pick2 = lambda r, k, h: OrderedDict(zip(h, r)).get(k)

pick3 = lambda r, ks, h: map(lambda t: t[0] in ks and t[1] or None,
                             OrderedDict(zip(h, r)).iteritems())


if __name__ == '__main__':
    key = 'Foo'
    headers = 'Bar', 'Foo'
    for row in ((5, 6), ('f', 'g'), (1, 8)):
        # Method 0
        print OrderedDict(Bar=row[0], Foo=row[1]).get(key)

        # Method 1
        print pick0(row, key)

        # Method 2
        print pick1(row, key, headers)

        # Method 3
        print pick2(row, key, headers)

        # Method 4
        print pick3(row, ('Foo', 'Bar'), headers)


The last three methods are generalised. The last method allows you to specify multiple keys to pick out.
The downside of all the functions, except pick0, is that the caller needs to know all the columns and their order. pick0 is even worse as it is not reusable.

I would rather implement something similar to csv.DictReader that would give me each row as a dict, or perhaps as a namedtuple

If the usage is as simple as in the given example, one could also simply do this:

key_index = headers.index(key)
for row in ((5, 6), ('f', 'g'), (1, 8)):
    print row[key_index]


Other comments:


Using locals() in pick0 is dubious. A caller trying to pick k or r would get unexpected results.
lambda is for creating nameless functions. Use def when you want to assign a name.