在Python中对字典列表应用函数

0 投票
2 回答
4688 浏览
提问于 2025-04-18 00:12

我想把一个叫offline_optimize的函数应用到一个输入列表上。这个列表里的每一项都是一个字典,字典里有14对键值对。这个列表总共有12个字典。

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

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

类型错误:offline_optimize() 需要14个参数(给了12个)

inputs是一个字典的列表。更准确地说,这个列表里有12个字典。

offline_optimize这个函数需要14个参数。

我该怎么用map函数处理这个字典列表呢?因为这些字典需要用双星号语法(**)拆开,才能传给offline_optimize函数接受的14个参数。

如果可以的话,我希望避免使用列表推导式。

2 个回答

0

根据你的错误信息,我猜测 offline_optimize() 这个函数的定义大概是这样的:

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

你可以把你的函数定义改成:

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

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

这个函数的作用是把一个函数应用到一个或多个序列(比如列表)里的每个元素上,然后返回一个新的列表,里面是应用函数后的结果。如果你给了多个序列,函数会同时拿每个序列里对应位置的元素来调用。如果某个序列的长度不一样,缺少的地方会用None来填补。 如果你传入的函数是None,那么它就会返回序列里的所有元素(如果有多个序列,就会返回一个包含元组的列表)。

我觉得用一些例子来说明这个效果会更好,比如模拟一下inputsoffline_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))]

这就是inputs的样子:

>>> 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}

你这样做:

>>> 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)]

你想要这样做:

>>> 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)]

你其实更想用列表推导式,而不是用有14个关键字参数的函数。

撰写回答