我有下面的函数function_iterate_over_array,它接受一个数组和一个函数名列表。虽然该函数确实有效,但我需要创建一个实现相同结果但可以接受任意数量的function_names的函数。
例如,以下函数必须包含四个函数名称
from operator import itemgetter
from itertools import groupby
from dictionary_functions import DictionaryFunctions
group_func = lambda iterable,key: [list(group) for key, group in groupby(sorted(iterable, key=itemgetter(key)), itemgetter(key))]
def add_one(i):
return i + 1
def subtract_one(i):
return i - 1
array = [{'f1':add_one,'f2':add_one,'f3':add_one,'f4':add_one},
{'f1':add_one,'f2':add_one,'f3':add_one,'f4':add_one},
{'f1':subtract_one,'f2':subtract_one,'f3':subtract_one,'f4':subtract_one},
{'f1':subtract_one,'f2':add_one,'f3':add_one,'f4':add_one}]
functions = ['f1','f2','f3','f4']
def function_iterate_over_array(array,functions,starting_value=0):
L = []
function_key_name = functions[0]
grouped_array = group_func(array,function_key_name)
for grouped_array_item in grouped_array:
function_one = grouped_array_item[0][function_key_name]
function_one_result = function_one(starting_value)
function_two_name = functions[1]
sub_grouped_array = group_func(grouped_array_item,function_two_name)
for sub_grouped_array_item in sub_grouped_array:
function_two = sub_grouped_array_item[0][function_two_name]
function_two_result = function_two(function_one_result)
function_three_name = functions[2]
sub_sub_grouped_array = group_func(sub_grouped_array_item,function_three_name)
for sub_sub_grouped_array_item in sub_sub_grouped_array:
function_three = sub_sub_grouped_array_item[0][function_three_name]
function_three_result = function_three(function_two_result)
function_four_name = functions[3]
sub_sub_sub_grouped_array = group_func(sub_sub_grouped_array_item,function_four_name)
for sub_sub_sub_grouped_array_item in sub_sub_sub_grouped_array:
function_four = sub_sub_sub_grouped_array_item[0][function_four_name]
function_four_result = function_four(function_three_result)
for dictionary_from_array in sub_sub_sub_grouped_array_item:
D = dict(dictionary_from_array.items()+{'result':function_four_result}.items())
L.append(D)
return L
L = function_iterate_over_array(array,functions)
#-->[{'f1': <function add_one at 0x1006d5cf8>, 'f2': <function add_one at 0x1006d5cf8>, 'f3': <function add_one at 0x1006d5cf8>, 'f4': <function add_one at 0x1006d5cf8>, 'result': 4}, {'f1': <function add_one at 0x1006d5cf8>, 'f2': <function add_one at 0x1006d5cf8>, 'f3': <function add_one at 0x1006d5cf8>, 'f4': <function add_one at 0x1006d5cf8>, 'result': 4}, {'f1': <function subtract_one at 0x100763ed8>, 'f2': <function add_one at 0x1006d5cf8>, 'f3': <function add_one at 0x1006d5cf8>, 'f4': <function add_one at 0x1006d5cf8>, 'result': 2}, {'f1': <function subtract_one at 0x100763ed8>, 'f2': <function subtract_one at 0x100763ed8>, 'f3': <function subtract_one at 0x100763ed8>, 'f4': <function subtract_one at 0x100763ed8>, 'result': -4}]
我希望用比function_iterate_over_array更好的函数来获得相同的结果,它可以使用任意数量的函数。例如,我希望以下工作:
array = [{'f1':add_one,'f2':add_one,'f3':add_one,'f4':add_one},
{'f1':add_one,'f2':add_one,'f3':add_one,'f4':add_one},
{'f1':subtract_one,'f2':subtract_one,'f3':subtract_one,'f4':subtract_one},
{'f1':subtract_one,'f2':add_one,'f3':add_one,'f4':add_one}]
function_iterate_over_array(array,['f1','f2'])
function_iterate_over_array(array,[&#39; f1&#39;,&#39; f2&#39;])应返回以下内容:
[{'f1': <function add_one at 0x101a0fcf8>, 'f2': <function add_one at 0x101a0fcf8>, 'f3': <function add_one at 0x101a0fcf8>, 'f4': <function add_one at 0x101a0fcf8>, 'f5': <function add_one at 0x101a0fcf8>, 'result': 2}, {'f1': <function add_one at 0x101a0fcf8>, 'f2': <function add_one at 0x101a0fcf8>, 'f3': <function add_one at 0x101a0fcf8>, 'f4': <function add_one at 0x101a0fcf8>, 'f5': <function add_one at 0x101a0fcf8>, 'result': 2}]
我通过将function_iterate_over_array更改为以下内容来实现:
def function_iterate_over_array(array,functions,starting_value=0):
L = []
function_key_name = functions[0]
grouped_array = group_func(array,function_key_name)
for grouped_array_item in grouped_array:
function_one = grouped_array_item[0][function_key_name]
function_one_result = function_one(starting_value)
function_two_name = functions[1]
sub_grouped_array = group_func(grouped_array_item,function_two_name)
for sub_grouped_array_item in sub_grouped_array:
function_two = sub_grouped_array_item[0][function_two_name]
function_two_result = function_two(function_one_result)
for dictionary_from_array in sub_grouped_array_item:
D = dict(dictionary_from_array.items()+{'result':function_two_result}.items())
L.append(D)
return L
我也希望以下工作
array = [{'f1':add_one,'f2':add_one,'f3':add_one,'f4':add_one,'f5':add_one},
{'f1':add_one,'f2':add_one,'f3':add_one,'f4':add_one,'f5':add_one}]
functions = ['f1','f2','f3','f4','f5']
function_iterate_over_array(array,functions)
特别是我正在寻找一种更好的方法来编写上述函数,以便它可以接受任意数量的函数。
答案 0 :(得分:3)
看起来reduce
可以帮到你很多。
将两个参数的函数累加到iterable的项中, 从左到右,以便将迭代减少到单个值。 例如,reduce(lambda x,y:x + y,[1,2,3,4,5])计算 ((((1 + 2)3)4)5)。左参数x是累计值和 正确的参数y是迭代的更新值。如果 可选的初始化程序存在,它放在项目之前 在计算中可迭代,并在迭代时用作默认值 是空的。如果没有给出初始化器,并且iterable只包含一个 item,返回第一个项目。
它专门设计用于将函数反复应用于值集合。使用lambda
,您可以在每一步使用不同的功能。
from functools import reduce
def add_one(i):
return i + 1
def subtract_one(i):
return i - 1
function_dicts = [{'f1':add_one,'f2':add_one,'f3':add_one,'f4':add_one},
{'f1':subtract_one,'f2':subtract_one,'f3':subtract_one,'f4':subtract_one},
{'f1':subtract_one,'f2':add_one,'f3':add_one,'f4':add_one}]
functions = ['f1','f2','f3','f4']
for function_dict in function_dicts:
result = reduce((lambda value, fname : function_dict[fname](value)), functions, 0)
print(result)
# 4
# -4
# 2
它不会返回与您的问题完全相同的格式,但这会提供所需的核心功能。
答案 1 :(得分:2)
虽然排序不同,但这似乎非常接近。我无法按照那种应该做的那样。如果你需要帮助恢复,你能解释那里的目标吗? (请注意,在Python 3中,您的排序甚至不起作用,因为函数不可排序。)
import pprint
def add_one(i):
return i + 1
def subtract_one(i):
return i - 1
function_dictionaries = [
{'f1': add_one, 'f2': add_one, 'f3': add_one, 'f4': add_one},
{'f1': add_one, 'f2': add_one, 'f3': add_one, 'f4': add_one},
{'f1': subtract_one, 'f2': subtract_one, 'f3': subtract_one, 'f4': subtract_one},
{'f1': subtract_one, 'f2': add_one, 'f3': add_one, 'f4': add_one}
]
def apply_functions(function_dictionaries, function_names, starting_value=0):
results = []
for d in function_dictionaries:
result = d.copy()
value = starting_value
for function_name in function_names:
value = d[function_name](value)
result['result'] = value
results.append(result)
return results
pprint.pprint(apply_functions(function_dictionaries, ['f1', 'f2', 'f3', 'f4']))
# Output:
# [{'f1': <function add_one at 0x10ae58048>,
# 'f2': <function add_one at 0x10ae58048>,
# 'f3': <function add_one at 0x10ae58048>,
# 'f4': <function add_one at 0x10ae58048>,
# 'result': 4},
# {'f1': <function add_one at 0x10ae58048>,
# 'f2': <function add_one at 0x10ae58048>,
# 'f3': <function add_one at 0x10ae58048>,
# 'f4': <function add_one at 0x10ae58048>,
# 'result': 4},
# {'f1': <function subtract_one at 0x10aec4048>,
# 'f2': <function subtract_one at 0x10aec4048>,
# 'f3': <function subtract_one at 0x10aec4048>,
# 'f4': <function subtract_one at 0x10aec4048>,
# 'result': -4},
# {'f1': <function subtract_one at 0x10aec4048>,
# 'f2': <function add_one at 0x10ae58048>,
# 'f3': <function add_one at 0x10ae58048>,
# 'f4': <function add_one at 0x10ae58048>,
# 'result': 2}]