我正在尝试改善代码的计算时间,因此我想用map函数替换循环。
对于字典中的每个键,我检查它是否大于特定值,并将其插入到同一键下的新字典中:
我的原始代码是:
dict1={'a':-1,'b':0,'c':1,'d':2,'e':3}
dict_filt = {}
for key in dict1.keys():
if dict1[key]>1:
dict_filt[key] = dict1[key]*10
print (dict_filt)
输出为:{'d':20,'e':30} 这有效 但是当我尝试使用地图时:
dict1={'a':-1,'b':0,'c':1,'d':2,'e':3}
dict_filt = {}
def for_filter (key):
if dict1[key]>1:
dict_filt[key] = dict1[key]*10
map (for_filter ,dict1.keys())
print (dict_filt)
我得到一个空字典
我试图使其与lambda一起使用:
map (lambda x: for_filter(x) ,dict1.keys())
或将字典定义为全局字典,但仍然无法正常工作。
很高兴获得帮助
我不需要原始字典,因此如果更容易处理一部字典,那还是可以的
答案 0 :(得分:1)
使用字典理解而不是map
:
{k: v * 10 for k, v in dict1.items() if v > 1}
代码:
dict1 = {'a':-1,'b':0,'c':1,'d':2,'e':3}
print({k: v * 10 for k, v in dict1.items() if v > 1})
# {'d': 20, 'e': 30}
答案 1 :(得分:0)
map
很懒:如果不使用这些值,则不会应用函数for_filter
。由于您正在使用副作用填充dict_filt
,因此除非您强行评估map
,否则什么都不会发生:
替换:
map(for_filter, dict1.keys())
通过:
list(map(for_filter, dict1)) # you don't need keys here
您将获得预期的结果。
但是请注意,这是对map
的滥用。您应该使用dict理解(请参阅@奥斯汀的答案)。
map
和惰性的更多信息。看the doc:
map(函数,可迭代,...)
返回一个迭代器,该迭代器将函数应用于所有可迭代项,并产生结果。
考虑以下功能:
>>> def f(x):
... print("x =", x)
... return x
...
此函数返回其参数,并且会产生副作用(打印值)。让我们尝试使用map
函数将此函数应用于简单范围:
>>> m = map(f, range(5))
什么都没有打印!让我们看一下m
的值:
>>> m
<map object at 0x7f91d35cccc0>
我们期待[0, 1, 2, 3, 4]
,但我们遇到了一个奇怪的<map object at 0x7f91d35cccc0>
。这很懒:map
并没有真正应用该功能,而是创建了一个迭代器。在每次next
调用中,此迭代器都会返回一个值:
>>> next(m)
x = 0
0
该值是将函数f
应用到映射的可迭代对象(range
)的下一个元素的结果。这里,0
是返回值,x = 0
是print
副作用的结果。 在这里重要的是,在将其拉出迭代器之前,此值不存在。因此,在将vlaue拉出迭代器之前,不会产生副作用。
如果我们继续调用下一步,将耗尽迭代器:
...
>>> next(m)
x = 4
4
>>> next(m)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
获取迭代器所有值的另一种方法是创建一个list
。 这不是强制转换,而是新对象的构造和旧对象的消耗:
>>> m = map(f, range(5))
>>> list(m)
x = 0
x = 1
x = 2
x = 3
x = 4
[0, 1, 2, 3, 4]
我们看到对范围的每个元素都产生了副作用print
,并且然后返回了列表[0, 1, 2, 3, 4]
。
在您的情况下,该函数不会打印任何内容,但是会分配给外部变量dict_filt
。除非您使用map
迭代器,否则该功能将不适用。
我再说一遍:不要使用map
(或任何列表/字典理解)来执行副作用({{1}来自功能世界,而副作用并不存在)。