鉴于字典 { 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 回答
没有这样的功能;最简单的方法是使用字典理解:
在python 2.7中,使用
.iteritems()
方法而不是.items()
来节省内存 . 直到python 2.7才引入dict理解语法 .请注意,列表上也没有这样的方法;你必须使用列表理解或
map()
函数 .因此,您也可以使用
map()
函数来处理您的dict:但那不是那么可读,真的 .
这些工具非常适合这种简单但重复的逻辑 .
http://toolz.readthedocs.org/en/latest/api.html#toolz.dicttoolz.valmap
得到你想要的地方 .
您可以就地执行此操作,而不是创建新的dict,这可能适用于大型词典(如果您不需要副本) .
结果
my_dictionary
包含:虽然我的原始答案忽略了这一点(通过尝试用Accessing key in factory of defaultdict的解决方案来解决这个问题),但我已经重新设计了它以提出对当前问题的实际解决方案 .
这里是:
用法:
我们的想法是将原始dict子类化,以赋予其所需的功能:在所有值上“映射”一个函数 .
加分点是,这个字典可用于存储原始数据,就像它是
dict
一样,同时使用回调转换请求中的任何数据 .当然,您可以随意按照您想要的方式命名类和函数(在本答案中选择的名称受PHP的array_walk()函数启发) .
注意:
try
-except
块和return
语句都不是必需的功能,它们可以进一步模仿PHP的array_walk
的行为 .由于PEP-0469将iteritems()重命名为items()和PEP-3113,删除了Tuple参数解包,因此在Python 3.x中你应该像这样编写Martijn Pieters♦ answer:
刚刚遇到这个用例 . 我实现了gens's answer,添加了一个递归方法来处理也是dicts的值:
在处理在Python 2中将字符串编码为字节的json或yaml文件时,这非常有用