python - 如何创建一个可以迭代数组中的项目中任意数量的函数的函数?

标签 python arrays loops group-by introspection

我有一个名为 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,['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)

特别是我正在寻找一种更好的方法来编写上述函数,以便它可以接受任意数量的函数。

最佳答案

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

Apply function of two arguments cumulatively to the items of iterable, from left to right, so as to reduce the iterable to a single value. For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5). The left argument, x, is the accumulated value and the right argument, y, is the update value from the iterable. If the optional initializer is present, it is placed before the items of the iterable in the calculation, and serves as a default when the iterable is empty. If initializer is not given and iterable contains only one item, the first item is returned.

它专门设计用于将函数反复应用于值集合。使用 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 - 如何创建一个可以迭代数组中的项目中任意数量的函数的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45393718/

相关文章:

php - 查找单词在句子中的位置和频率

c++ - 正确打印字符数组地址的方法

python - 为什么这是 python 中的无限循环?

python - 提交后django清除表单字段

arrays - 用未知数的字符串填充动态数组

java - 如何用一个循环遍历二维数组?

javascript - 无限循环不起作用

python - 使用 NTP 的事件同步

python - 按首字母查找列表项并将其存储在两个不同的列表中并合并到字典中

python - Opencv角点检测