在python中,我使用的是肉馅map-reduce框架
从我的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
请让我知道如何解决此错误。
首先,使用 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}}
然后,您的归约函数可能会变为
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}
使用 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...))
压缩它们会给你((k1,v1), (k2,v2), (k3,v3)...)
,这就是你想要
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
最初这样做。相反,我们需要检查字典中的键,值对。但是,由于我们需要处理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)