2017-07-29 40 views
1

我有下面的函數稱爲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

回答

3

它看起來像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 

不退還完全一樣的格式,如你的問題,但是這提供了所需的核心功能。

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}] 
相關問題