Zip и применить список функций по списку значений в Python

Есть ли идиоматический и/или элегантный Python для zipping и применения списка функций над списком значений?

Например, предположим, что у вас есть список функций:

functions = [int, unicode, float, lambda x: '~' + x + '~']

и список значений:

values = ['33', '\xc3\xa4', '3.14', 'flange']

Есть ли способ применить i-я функцию к i-му значению и вернуть список той же длины преобразованных значений, избегая при этом уродливого понимания списка?

[functions[i](values[i]) for i in range(len(functions))] # <- ugly

Я хочу что-то вроде zip() + map() (zipmap()!) списка функций со списком значений и применять функции к их парным значениям. Я думал, что itertools может предложить что-то актуальное, но такие функции, как imap и starmap, предназначены для сопоставления одной функции над итерируемым, а не итерируемым функциями над другим итерабельным.

Ответы

Ответ 1

Эти решения кажутся чрезмерно сложными: map уже застегивает свои аргументы:

map(lambda x,y:x(y), functions, values)

Или, если вы предпочитаете версию итератора:

from itertools import imap
imap(lambda x,y:x(y), functions, values)

Ответ 2

[x(y) for x, y in zip(functions, values)]

Ответ 3

Одна из красивейших особенностей функциональной инкапсуляции заключается в том, что они могут скрывать уродство.

Если вам нужно zipmap, определите его:

def zipmap(values, functions):
    return [functions[i](values[i]) for i in range(
      len(functions))]

Ответ 4

Код, который должен функционировать надежно, сделал бы это в цикле for, чтобы он мог обеспечить значимую отчетность об ошибках:

for i in xrange(num_columns):
    try:
        outrow.append(functions[i](input_values[i])
    except (ValueError, EtcetcError) as e:
        self.do_error_reporting(row_number, i, input_value[i], e)
        outrow.append(None)