从dict中过滤项目并处理子集

时间:2016-02-12 00:53:08

标签: python dictionary functional-programming

我有一个字典列表,我想选择与单独列表中的键对应的项目(注意:我们可以假设每个keys_of_interest = ['a', 'b'] all_items =[ {'a' : value_a1, 'b' : value_b1, 'c' : ...}, {'a' : value_a2, 'b' : value_b2, 'c' : ...}, ... ] 包含键)。此外,我想处理所选项目的子集

作为一个例子,给出:

a

我想要的结果是通过提取与bfun相对应的值并仅将a应用于[ [fun(value_a1), value_b1], [fun(value_a2), value_b2], ... ] 来获得的,即:

from operator import itemgetter
[itemgetter(*keys_of_interest)(el) for el in all_items]

密钥提取部分可以通过以下方式完成:

{{1}}

是否有任何(优雅)方式将itemgetter与函数

结合起来

4 个答案:

答案 0 :(得分:1)

可能没有超级整洁的方法来做到这一点。一种方法可能是:

getter = itemgetter(*keys_of_interest[1:])
def process_dict(d):
    return_value = [fun(d[keys_of_interest[0]])]
    return_value.extend(getter(d))
    return return_value

result = [process_dict(d) for d in all_items]

如果你的目标是一个最新版本的python,这可以通过一点点下载来完成...

first_key, *other_keys = keys_of_interest
getter = itemgetter(*other_keys)
def process_dict(d):
    return_value = [fun(d[first_key])]
    return_value.extend(getter(d))
    return return_value

答案 1 :(得分:1)

这太不优雅了吗?

from operator import itemgetter
result = [(f(x), *others) for x, *others in [
    itemgetter(*keys_of_interest)(el) for el in all_items]
    ]

或旧版本:

from operator import itemgetter
result = [(f(x[0]), x[1:]) for x in [
    itemgetter(*keys_of_interest)(el) for el in all_items]
    ]

答案 2 :(得分:1)

Python 3.5+解决方案:

设置:

>>> from operator import itemgetter
>>> keys_of_interest = ['a', 'b', 'c'] # 3 keys to show unpacking at work
>>> all_items = [{'a': 1, 'b': 2, 'c': 3, 'd': 4}, {'a': 5, 'b': 6, 'c': 7, 'd': 8}]
>>> fun = str # some silly demo function

应用map和Python 3.5解包:

>>> list(map(lambda x: (fun(x[0]), *x[1:]),
...     (itemgetter(*keys_of_interest)(el) for el in all_items)))
[('1', 2, 3), ('5', 6, 7)]

答案 3 :(得分:1)

如果优先是优先事项,您可以先转换dicts,然后使用itemgetter而无需进一步调整。为此,您需要将要应用函数的键与您想要原始值的键分开 - 我认为这在任何情况下都是好事。

首先,设置

keys_of_interest = ['a', 'b', 'c', 'd']
keys_for_func = ['a', 'b']  # with this approach you can apply a func to multiple keys

func = lambda x: x ** 2  # for demo
all_dicts = [{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5},
             {'a': 6, 'b': 7, 'c': 8, 'd': 9, 'e': 10}]

然后这就是我要做的事情:

transformed = ({k: func(v) if k in keys_for_func else v for k, v in d.items()}
               for d in all_dicts)
result = list(map(itemgetter(*keys_of_interest), transformed))

结果:

[(1, 4, 3, 4), (36, 49, 8, 9)]