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(*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):

上記の関数シグネチャは 2 つの引数を取ります。関数に渡される引数は、それぞれkおよびを介してアクセスされvます。したがって、 を呼び出すと、割り当てられ、割り当てられreducefn({"key1":"value"},{"key2":"value"})ます。k{"key1":"value"}v{"key2":"vlaue"}

次のように呼び出そうとするとreducefn(dic1,dic2,dic3,...)、の宣言/署名で定義されている許容数を超えるパラメーターを渡していますreducefn

for k,val in (k,v):

ここで、 に 2 つの辞書を渡したとすると、 とreducefnの両方が辞書になります。上記の for ループは次と同等です。kv

>>> 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):になるため、意味がありません。代わりに、辞書のキーと値のペアを調べる必要があります。しかし、n個の辞書に対処する必要があるため、関数定義を再考する必要があります。kvalkv

したがって:

def reducefn(*dicts):

次のように関数を呼び出すと:

reducefn({'physics': 1},{'volume': 1, 'chemistry': 1},{'chemistry': 1})

*dicts最終的に次のような方法で引数を収集しますdicts

({'physics': 1}, {'volume': 1, 'chemistry': 1}, {'chemistry': 1})

ご覧のとおり、関数に渡された 3 つの辞書が 1 つのタプルにまとめられています。次に、タプルを反復処理します。

for dic in dicts:

これで、反復ごとに dic が渡された辞書の 1 つになったので、次に進み、その中のキーと値のペアを出力します。

for k,v in dic.items(): 
    print(k,v) 
于 2013-05-01T12:36:00.573 に答える
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...))

それらをzipすること((k1,v1), (k2,v2), (k3,v3)...)で、あなたが望むものを得ることができます

于 2013-05-01T12:39:12.287 に答える