如何创建一个函数,该函数可以迭代数组中某个项目内的任意数量的函数?

问题描述:

我有下面的函数称为function_iterate_over_array,它接受一个数组和函数名称列表。虽然函数确实有效,但我需要创建一个函数来获得相同的结果,但可以使用任意数量的函数名。如何创建一个函数,该函数可以迭代数组中某个项目内的任意数量的函数?

例如,下面的函数必须在四个功能名称

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(阵列,[ 'F1', 'F2'])应当返回以下:

[{'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) 

特别是我正在寻找更好的方式来编写上述函数,以便它可以采用任意数量的函数。

+1

你想要什么来实现这些功能呢? 'function_iterate_over_array(array,['f1','f2'])'的输出应该是什么? –

+0

好点 - 只是更新我的问题,添加这些细节。 – Chris

+0

概念上这个功能的目的是什么? – Quelklef

它看起来像reduce可以帮助你很多。

将两个参数的函数累积地应用到可迭代项 从左到右,以便将迭代次数减少为单个值。例如,reduce(lambda x,y:x + y,[1,2,3,4,5])计算 ((((1 + 2)+3)+4)+5)。左边的参数x是累加值,并且 正确的参数y是来自可迭代的更新值。如果 可选初始值设定项存在,则将其放置在计算中可迭代的 的项目之前,并且当可迭代对象 为空时用作默认值。如果初始化程序没有给出并且可迭代只包含一个 项目,则返回第一个项目。

它专门设计用于将函数反复应用于一组值。使用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 

不退还完全一样的格式,如你的问题,但是这提供了所需的核心功能。

虽然顺序不同,但这似乎很接近。我无法追随那种本应该做的事情。如果你需要恢复的帮助,你能解释一下那里的目标吗? (请注意,在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}]