2013-05-01 39 views
4

在Python中,我使用的是肉餡的map-reduce框架如何通過一個字典作爲值的函數在python

從我的地圖功能我想在一個循環yield (k,v),這將輸出發送到減少功能(給出的樣本數據是我的地圖功能的輸出)

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

會有很多這樣的條目;這僅僅是一個例子。

這裏,auth3auth34是鍵和相應的值是字典項

裏面的減少功能,當我嘗試打印鍵,值,我收到「太多值解壓」的錯誤。我的減少功能看起來像這樣

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

請讓我知道如何解決此錯誤。

回答

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

函數簽名上面有兩個參數。傳遞給函數的參數分別通過kv訪問。因此調用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代表同樣的事情kv最初做過。相反,我們需要查看字典中的鍵值對。但看到我們需要應付n個字典,我們需要重新思考函數定義。

因此:

def reducefn(*dicts): 

當你調用該函數是這樣的:

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

*dicts收集論據,以這樣的方式dicts作爲結束:

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

正如你所看到的,傳入這個函數的三個字典是收集的d變成一個元組。現在,我們遍歷元組:

for dic in dicts: 

所以,現在,在每次迭代,DIC是我們通過在字典中的一個,所以現在我們繼續前進,打印出key,value對裏面:

for k,v in dic.items(): 
    print(k,v) 
+0

也許不錯也讓O P知道這是爲什麼,而他/她不是...... – akaIDIOT 2013-05-01 12:37:33

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...))

zippping他們給你((k1,v1), (k2,v2), (k3,v3)...)並且那你想

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}} 

然後,您減少功能可能會爲

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} 
相關問題