首页 文章

映射python字典中的值

提问于
浏览
173

鉴于字典 { 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)

也就是说,如果原始字典发生变异或创建了副本,对我来说并不重要 .

6 回答

  • 4

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

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

    但那不是那么可读,真的 .

  • 2

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

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

    得到你想要的地方 .

    import toolz
    def f(x):
      return x+1
    
    toolz.valmap(f, my_list)
    
  • 253

    您可以就地执行此操作,而不是创建新的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}
    
  • 19

    虽然我的原始答案忽略了这一点(通过尝试用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子类化,以赋予其所需的功能:在所有值上“映射”一个函数 .

    加分点是,这个字典可用于存储原始数据,就像它是 dict 一样,同时使用回调转换请求中的任何数据 .

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

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

  • 0

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

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

    刚刚遇到这个用例 . 我实现了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文件时,这非常有用

相关问题