在Python中对字典列表应用函数
我想把一个叫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,那么它就会返回序列里的所有元素(如果有多个序列,就会返回一个包含元组的列表)。
我觉得用一些例子来说明这个效果会更好,比如模拟一下inputs
和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))]
这就是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个关键字参数的函数。