4

在 python 中,我使用的是 mincemeat map-reduce 框架

从我的地图函数中,我想yield (k,v)在一个循环中,它将输出发送到reduce函数(给出的样本数据是我的地图函数的输出)

auth3 {'practical': 1, 'volume': 1, 'physics': 1} 
auth34 {'practical': 1, 'volume': 1, 'chemistry': 1}
....

会有很多这样的条目;这只是几个例子。

在这里,auth3auth34是键,各自的值是字典项

当我尝试打印键值时,在 reduce 函数内部,我收到“太多值无法解包”错误。我的 reduce 函数看起来像这样

def reducefn(k, v):     
    for k,val in (k,v):
        print k, v

请让我知道如何解决此错误。

4

3 回答 3

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}
于 2013-05-01T13:05:26.330 回答
0

使用拉链

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)...),这就是你想要的

于 2013-05-01T12:39:12.287 回答
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,两者kv都是字典。上面的 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的相同的事情。相反,我们需要检查字典中的键值对。但是看到我们需要处理 n 个字典,我们需要重新考虑函数定义。kv

因此:

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) 
于 2013-05-01T12:36:00.573 回答