映射python字典中的值

时间:2012-09-01 15:31:37

标签: python dictionary map-function

给定字典{ k1: v1, k2: v2 ... }我想提供{ k1: f(v1), k2: f(v2) ... }我提供的函数f

有没有这样的内置功能?或者我必须做什么

dict([(k, f(v)) for (k, v) in my_dictionary.iteritems()])

理想情况下我会写

my_dictionary.map_values(f)

my_dictionary.mutate_values_with(f)

也就是说,如果原始字典发生变异或创建了副本,对我来说无关紧要。

7 个答案:

答案 0 :(得分:276)

没有这样的功能;最简单的方法是使用字典理解:

my_dictionary = {k: f(v) for k, v in my_dictionary.items()}

在python 2.7中,使用.iteritems()方法而不是.items()来节省内存。直到python 2.7才引入dict理解语法。

请注意,列表上也没有这样的方法;你必须使用列表理解或map()函数。

因此,您也可以使用map()函数处理您的dict:

my_dictionary = dict(map(lambda kv: (kv[0], f(kv[1])), my_dictionary.iteritems()))

但那不可读,真的。

答案 1 :(得分:22)

这些工具非常适合这种简单但重复的逻辑。

http://toolz.readthedocs.org/en/latest/api.html#toolz.dicttoolz.valmap

让你正确到达目的地。

import toolz
def f(x):
  return x+1

toolz.valmap(f, my_list)

答案 2 :(得分:19)

您可以就地执行此操作,而不是创建新的dict,这对于大型词典(如果您不需要副本)可能更合适。

def mutate_dict(f,d):
    for k, v in d.iteritems():
        d[k] = f(v)

my_dictionary = {'a':1, 'b':2}
mutate_dict(lambda x: x+1, my_dictionary)

导致my_dictionary包含:

{'a': 2, 'b': 3}

答案 3 :(得分:4)

虽然我的原始答案忽略了这一点(通过尝试用Accessing key in factory of defaultdict的解决方案来解决这个问题),但我已经重新设计了它以提出对当前问题的实际解决方案。

这是:

class walkableDict(dict):
  def walk(self, callback):
    try:
      for key in self:
        self[key] = callback(self[key])
    except TypeError:
      return False
    return True

用法:

>>> d = walkableDict({ k1: v1, k2: v2 ... })
>>> d.walk(f)

这个想法是将原始字典子类化,以赋予它所需的功能:"映射"对所有值的函数。

优点是,这个字典可用于存储原始数据,就好像它是dict一样,同时通过回调转换请求中的任何数据。

当然,您可以随意按照您想要的方式命名类和函数(在此答案中选择的名称受PHP' array_walk()函数的启发。)

注意:try - except块和return语句都不是必需的功能,它们可以进一步模仿PHP的行为。 s array_walk

答案 4 :(得分:3)

由于PEP-0469将iteritems()重命名为items()和PEP-3113,删除了 Tuple参数解包,因此在Python 3.x中你应该写{{3}像这样:

my_dictionary = dict(map(lambda item: (item[0], f(item[1])), my_dictionary.items()))

答案 5 :(得分:0)

刚刚遇到这个用例。我实现了gens's answer,添加了一个递归方法来处理也是dicts的值:

def mutate_dict_in_place(f, d):
    for k, v in d.iteritems():
        if isinstance(v, dict):
            mutate_dict_in_place(f, v)
        else:
            d[k] = f(v)

# Exemple handy usage
def utf8_everywhere(d):
    mutate_dict_in_place((
        lambda value:
            value.decode('utf-8')
            if isinstance(value, bytes)
            else value
        ),
        d
    )

my_dict = {'a': b'byte1', 'b': {'c': b'byte2', 'd': b'byte3'}}
utf8_everywhere(my_dict)
print(my_dict)

在处理在Python 2中将字符串编码为字节的json或yaml文件时,这非常有用

答案 6 :(得分:0)

为避免从lambda内部进行索引,例如:

rval = dict(map(lambda kv : (kv[0], ' '.join(kv[1])), rval.iteritems()))

您也可以这样做:

rval = dict(map(lambda(k,v) : (k, ' '.join(v)), rval.iteritems()))