在python中,我使用的是mincemeat map-reduce framework
从我的map函数中我想在循环中yield (k,v)
,它会将输出发送到reduce函数(给出的样本数据是我的map函数的输出)
auth3 {'practical': 1, 'volume': 1, 'physics': 1}
auth34 {'practical': 1, 'volume': 1, 'chemistry': 1}
....
会有很多这样的参赛作品;这只是一些例子。
此处,auth3
和auth34
是键,相应的值是字典项
当我尝试打印键值时,在reduce函数内部,我得到“解压缩的值太多”错误。我的reduce函数看起来像这样
def reducefn(k, v):
for k,val in (k,v):
print k, v
请告诉我如何解决此错误。
答案 0 :(得分:1)
首先,使用python内置dict
>>> dic1 = dict(auth3 = {'practical': 1, 'volume': 1, 'physics': 1},
auth34 = {'practical': 1, 'volume': 1, 'chemistry': 1} )
>>> dic1
{'auth3': {'practical': 1, 'volume': 1, 'physics': 1},
'auth34': {'practical': 1, 'volume': 1, 'chemistry': 1}}
然后,您的reduce函数可能会
def reducefn(dictofdicts):
for key, value in dictofdicts.iteritems() :
print key, value
最后,
>>> reducefn(dic1)
auth3 {'practical': 1, 'volume': 1, 'physics': 1}
auth34 {'practical': 1, 'volume': 1, 'chemistry': 1}
答案 1 :(得分:0)
def reducefn(*dicts): #collects multiple arguments and stores in dicts
for dic in dicts: #go over each dictionary passed in
for k,v in dic.items(): #go over key,value pairs in the dic
print(k,v)
reducefn({'practical': 1, 'volume': 1, 'physics': 1} ,{'practical': 1, 'volume': 1, 'chemistry': 1})
可生产
>>>
physics 1
practical 1
volume 1
chemistry 1
practical 1
volume 1
现在,关于你的实施:
def reducefn(k, v):
上面的函数签名有两个参数。传递给函数的参数分别通过k
和v
访问。因此,reducefn({"key1":"value"},{"key2":"value"})
的调用会导致k
被分配{"key1":"value"}
而v
被分配{"key2":"vlaue"}
。
当您尝试像这样调用它时:reducefn(dic1,dic2,dic3,...)
传入的内容超过reducefn
的声明/签名所定义的允许数量的参数。
for k,val in (k,v):
现在,假设您将两个词典传递给reducefn
,k
和v
都将成为词典。上面的for循环等同于:
>>> a = {"Name":"A"}
>>> b = {"Name":"B"}
>>> for (d1,d2) in (a,b):
print(d1,d2)
出现以下错误:
ValueError: need more than 1 value to unpack
这是因为你在调用for循环时实际上是这样做的:
d1,d2=a
当我们在REPL中尝试时,您会看到我们收到此错误
>>> d1,d2=a
Traceback (most recent call last):
File "<pyshell#24>", line 1, in <module>
d1,d2=a
ValueError: need more than 1 value to unpack
我们可以这样做:
>>> for (d1,d2) in [(a,b)]:
print(d1,d2)
{'Name': 'A'} {'Name': 'B'}
将元组 (a,b)
分配给d1,d2
。这称为解包,看起来像这样:
d1,d2 = (a,b)
但是,在我们的for循环for k,val in (k,v):
中,我们最终会使用k
,而val
表示与k
相同的内容,v
{ {1}}最初做过。相反,我们需要检查字典中的键值对。但看到我们需要处理n个字典,我们需要重新思考函数定义。
因此:
def reducefn(*dicts):
当你调用这样的函数时:
reducefn({'physics': 1},{'volume': 1, 'chemistry': 1},{'chemistry': 1})
*dicts
以dicts
结尾的方式收集论据:
({'physics': 1}, {'volume': 1, 'chemistry': 1}, {'chemistry': 1})
正如您所看到的,传递给函数的三个字典被收集到一个元组中。现在我们迭代元组:
for dic in dicts:
所以现在,在每次迭代中,dic是我们传入的字典之一,所以现在我们继续打印出其中的键值对:
for k,v in dic.items():
print(k,v)
答案 2 :(得分:0)
使用zip
def reducefn(k, v):
for k,val in zip(k,v):
print k, v
>>> reducefn({'practical': 1, 'volume': 1, 'physics': 1} ,{'practical': 1, 'volume': 1, 'chemistry': 1})
practical {'practical': 1, 'volume': 1, 'chemistry': 1}
volume {'practical': 1, 'volume': 1, 'chemistry': 1}
physics {'practical': 1, 'volume': 1, 'chemistry': 1}
>>>
reducefn(k,v)
:构成元组((k1,k2,k3..), (v1,v2,v3...))
zippping他们会给你((k1,v1), (k2,v2), (k3,v3)...)
,那就是你想要的