python字典中的值映射

python字典中的值映射,python,dictionary,map-function,Python,Dictionary,Map Function,给定一个字典{k1:v1,k2:v2…}如果我传递一个函数f,我想得到{k1:f(v1,k2:f(v2)…} 有没有这样的内置功能?或者我必须做什么 dict([(k, f(v)) for (k, v) in my_dictionary.iteritems()]) 理想情况下,我只会写信 my_dictionary.map_values(f) 或 也就是说,对我来说,原版词典是经过变异还是复制,都无关紧要。没有这样的功能;最简单的方法是使用听写理解: my_dictionary = {k:

给定一个字典
{k1:v1,k2:v2…}
如果我传递一个函数
f
,我想得到
{k1:f(v1,k2:f(v2)…}

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

dict([(k, f(v)) for (k, v) in my_dictionary.iteritems()])
理想情况下,我只会写信

my_dictionary.map_values(f)


也就是说,对我来说,原版词典是经过变异还是复制,都无关紧要。

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

my_dictionary = {k: f(v) for k, v in my_dictionary.items()}
在python 2.7中,使用
.iteritems()
方法而不是
.items()
来节省内存。直到Python2.7才引入dict理解语法

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

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

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

但这并不是那么可读,真的。

这些toolz非常适合这种简单但重复的逻辑

把你带到你想去的地方

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

toolz.valmap(f, my_list)

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

在my_dictionary中的结果包含:

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

虽然我最初的回答没有抓住要点(通过尝试用解决问题的方法来解决这个问题),但我对其进行了修改,以提出当前问题的实际解决方案

这是:

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函数的启发)

注意:
try
-
除了
块和
return
语句对于功能来说都不是必需的,它们是为了进一步模拟PHP的
数组行走

的行为,因为它将iteritems()重命名为items(),并删除了元组参数解包,在Python 3.x中,您应该这样编写:

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

刚刚遇到这个用例。我实现了,添加了一种递归方法来处理同样是dict的值:

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文件时非常有用,以避免从lambda内部进行索引,例如:

rval=dict(map(lambda-kv:(kv[0],''.join(kv[1])),rval.iteritems())
您还可以执行以下操作:

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

+1:我也会这么做
dict(zip(a,map(f,a.values()))
稍微短一点,但我必须考虑它在做什么,并提醒自己,如果dict没有改变,键和值将以相同的顺序迭代。我根本不必考虑dictcomp在做什么,所以这是正确的答案。@chiborg:这是因为您现在使用的不是一次查找所有键值对,而是多次使用键次数
my\u字典。\uuuu getitem\uuu
调用。请注意,因为(在python 3.x中实现)元组参数不再受支持:
lambda(k,v):(k,f(v))
将被重写为类似于
lambda k_v:(k_v[0],f(k_v[1])的内容。
为什么参数解包被禁用?这是一个怎样的改进?来自FP语言的Python看起来非常笨拙。编写示例的更好方法是在mydict.iteritems()中为k,v指定
dict((k,f(v))
,即没有方括号,这将阻止通过生成器创建中间列表。酷,您可能应该将
mapdict
重命名为
mutate\u values\u,使用
或其他一些东西来清楚地表明您重写了dict!:)
zip(d.keys(),d.values())
适用于更多版本,而不是
iteritems()
@ytpillai'zip'或comprehensions复制,而不是就地更改值,这就是我回答的目的。接受的答案是最好的,当副本是确定的。我很抱歉,我没有意识到你想要使用的项目方法。但是,对于非Python 2.7用户,
{k:f(v)for k,v in iter(d.items())}
通过生成迭代器节省了空间,这无法解决OP问题,因为我们要转换的现有密钥不会调用
\u missing\u
方法,除非工厂方法通过使用原点DICT作为回退,但这不是示例用法的一部分,我认为这是对手头问题的一个不令人满意的答案。哪些现有键?从OP:<代码>给定字典{K1:V1,K2:V2…}…< /代码>。也就是说,你已经有了一个
dict
开始..我想说我们都是对的;但我相信我们都错了。你是对的,我的答案不能回答这个问题;但不是因为你调用的原因。我只是没有抓住要点,给出了一种获得
{v1:f(v1),v2:f(v2),…}
给定
[v1,v2,…]
的方法,并且没有给出一条命令。我将编辑我的答案以更正这一点。在第二个示例中,这是对2元组本身的巧妙操作。但是,它在lambda中使用自动元组解包,这在Python 3中不再受支持。因此,
lambda(k,v)
将不起作用。看见
my_dictionary = dict(map(lambda item: (item[0], f(item[1])), my_dictionary.items()))
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)