Ответ 1
Эти решения кажутся чрезмерно сложными: map
уже застегивает свои аргументы:
map(lambda x,y:x(y), functions, values)
Или, если вы предпочитаете версию итератора:
from itertools import imap
imap(lambda x,y:x(y), functions, values)
Есть ли идиоматический и/или элегантный 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
, предназначены для сопоставления одной функции над итерируемым, а не итерируемым функциями над другим итерабельным.
Эти решения кажутся чрезмерно сложными: map
уже застегивает свои аргументы:
map(lambda x,y:x(y), functions, values)
Или, если вы предпочитаете версию итератора:
from itertools import imap
imap(lambda x,y:x(y), functions, values)
[x(y) for x, y in zip(functions, values)]
Одна из красивейших особенностей функциональной инкапсуляции заключается в том, что они могут скрывать уродство.
Если вам нужно zipmap
, определите его:
def zipmap(values, functions):
return [functions[i](values[i]) for i in range(
len(functions))]
Код, который должен функционировать надежно, сделал бы это в цикле 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)