在python字典中映射值

给定一个字典{ 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)

也就是说,对我来说,原始字典是否发生了突变或创建了一个副本都无关紧要。

435237 次浏览

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

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

在python 2.7中,使用.iteritems()方法代替.items()来节省内存。字典理解语法直到python 2.7才被引入。

注意,在列表上也没有这样的方法;你必须使用列表推导式或map()函数。

因此,你也可以使用map()函数来处理你的字典:

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

但这并不是那么可读。

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

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

带你去你想去的地方。

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


toolz.valmap(f, my_list)

您可以在原地执行此操作,而不是创建一个新的字典,这可能更适合大型字典(如果您不需要副本)。

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}

虽然我最初的答案错过了这一点(通过尝试解决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的array_walk的行为。

由于pep - 0469将iteritems()重命名为items(),而pep - 3113删除了元组参数解包,在Python 3中。x你应该这样写马丁·彼得的♦答案:

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

刚刚遇到这个用例。我实现了一族的回答,添加了一种递归方法来处理同样是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文件时非常有用

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

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

你还可以:

rval = dict(map(lambda(k,v) : (k, ' '.join(v)), rval.iteritems()))
  • 我的方式映射字典
def f(x): return x+2
bill = {"Alice": 20, "Bob": 10}
d = {map(lambda x: f(x),bill.values())}
print('d: ',dict(d))

结果

: d:  {22: 12}
  • 在字典的值中映射可迭代对象
bills = {"Alice": [20, 15, 30], "Bob": [10, 35]}
d= {map(lambda v: sum(v),bills.values())}
g= dict(map(lambda v: (v[0],sum(v[1])),bills.items()))
# prints
print('d: ',dict(d))
print('g: ',g)

结果

d:  {65: 45}
g:  {'Alice': 65, 'Bob': 45}