简体   繁体   中英

Apply a function to a list of dictionaries in python

I would like to apply a function (called offline_optimize ) to a list of inputs. Each item in the list is a dictionary with 14 key-value pairs. The list consists of 12 dictionaries.

# This works
results = [offline_optimize(**input) for input in inputs]

# This doesn't
results = map(offline_optimize, *inputs)

TypeError: offline_optimize() takes exactly 14 arguments (12 given)

inputs is a list of dictionaries. More precisely, the list consists of 12 dictionaries.

The function offline_optimize takes 14 arguments.

How can I use the map function on a list of dictionaries, when the dictionaries need to be unpacked (using the double-star syntax **) to 14 arguments to be accepted by the function offline_optimize ?

I would like to avoid list comprehensions, if possible.

map(function, sequence[, sequence, ...]) -> list

Return a list of the results of applying the function to the items of the argument sequence(s). If more than one sequence is given, the function is called with an argument list consisting of the corresponding item of each sequence, substituting None for missing values when not all sequences have the same length. If the function is None, return a list of the items of the sequence (or a list of tuples if more than one sequence).

I think the effect is best illustrated by mocking out inputs and offline_optimize :

import string


inputs = [dict([(s, i) for i, s in enumerate(string.letters[:14])])] * 12

def offline_optimize(*args, **kwargs):
    return [("args", args),
            ("args_count", len(args)),
            ("kwargs", kwargs),
            ("kwargs_count", len(kwargs))]

What inputs look like:

>>> print len(inputs), len(inputs[0]), inputs[0]
12 14 {'A': 0, 'C': 2, 'B': 1, 'E': 4, 'D': 3, 'G': 6, 'F': 5, 'I': 8, 'H': 7, 'K': 10, 'J': 9, 'M': 12, 'L': 11, 'N': 13}

You do this:

>>> mapped = map(offline_optimize, *inputs)
>>> print len(mapped), mapped[0]
14 [('args', ('A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A')), ('args_count', 12), ('kwargs', {}), ('kwargs_count', 0)]

You want to do this:

>>> mapped = map(lambda x: offline_optimize(**x), inputs)
>>> print len(mapped), mapped[0]

12 [('args', ()), ('args_count', 0), ('kwargs', {'A': 0, 'C': 2, 'B': 1, 'E': 4, 'D': 3, 'G': 6, 'F': 5, 'I': 8, 'H': 7, 'K': 10, 'J': 9, 'M': 12, 'L': 11, 'N': 13}), ('kwargs_count', 14)]

You really want to use list comprehensions and to avoid functions with 14 keyword parameters.

Based on your error, I'm assuming that offline_optimize() has a function signature something like the following:

def offline_optimize(arg1, arg2, maybe_arg3=some_default_value, ...):
    some_function(arg1)
    some_function(arg2, maybe_arg3)
    # etc.

Change your function definition to:

def offline_optimize(**kwargs):
    some_function(kwargs.get('arg1'))
    some_function(kwargs.get('arg2'), kwargs.get('maybe_arg3', some_default_value))
    # etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM