2011-08-11 68 views
1

我想在python中構建一個函數,該函數產生兩個字典的值,如果dict1的特定值匹配dict2的特定值。我的功能看起來是這樣的:幫助在元組匹配Python函數中使用* args

def dict_matcher(dict1, dict2, item1_pos, item2_pos): 
"""Uses a tuple value from dict1 to search for a matching tuple value in dict2. If a match is found, the other values from dict1 and dict2 are returned.""" 
for item1 in dict1: 
    for item2 in dict2: 
     if dict1[item1][item1_pos] == dict2[item2][item2_pos]: 
      yield(dict1[item1][2], dict2[item2][6]) 

我使用dict_matcher這樣的:

matches = [myresults for myresults in dict_matcher(dict1, dict2 , 2, 6)] 
print(matches) 

當我打印matches我得到這樣正確地匹配dict1和dict2值的列表:

[('frog', 'frog'), ('spider', 'spider'), ('cricket', 'cricket'), ('hampster', 'hampster')]

如何向此函數添加可變參數,以便除了打印每個d的匹配值ictionary,我還可以在dict1[item1][2] and dict2[item2][6]匹配的情況下打印每個字典項目的其他值?我可以使用*參數嗎?謝謝您的幫助。

編輯: 好吧,似乎有一些混淆,我試圖做什麼讓我嘗試另一個例子。

dict1 = {1: ('frog', 'green'), 2: ('spider', 'blue'), 3: ('cricket', 'red')}

dict2 = {a: ('frog', 12.34), b: ('ape', 22.33), c: ('lemur', 90.21)}

dict_matcher(dict1, dict2, 0, 0)會發現[0]從dict2 dict1和值[0]的值匹配的值。在這種情況下,唯一的比賽是'青蛙'。我上面的功能是這樣做的。我想要做的是擴展功能,以便能夠打印出我想要在函數參數中指定的dict1[value][0] == dict2[value][0]字典項目中的其他值。

+0

也許我只是愚蠢,但你的問題似乎混淆。值2和6在調用中用於item1_pos和item2_pos(args爲空),但它們看起來好像是後來的args(以某種奇怪的方式對我來說毫無意義)。 –

+0

@andrewcooke對不起,我發現它很混亂。我更新了我的問題,所以我希望現在更清楚。 – drbunsen

+0

嗯。在初始代碼塊中它是否也應該是'yield(dict1 [item1] [item1_pos],dict2 [item2] [item2_pos])' –

回答

0

你說你叫它爲

matches = [myresults for myresults in dict_matcher(dict1, dict2 , 2, 6)] 

你應該叫它爲

matches = list(dict_matcher(dict1, dict2 , 2, 6)) 

和它的簽名是

def dict_matcher(dict1, dict2, item1_pos, item2_pos, *args): 

所以4個參數過去了,4命名參數。所以*args結果在args = None

我不知道你想要什麼,但如果你

yield dict1[item1][item1_pos], dict2[item2][item2_pos] 

你會得到同樣的事情,你做

yield dict1[item1][2], dict2[item2][6] 

得到如果你想要得到的

yield dict1[item1], dict2[item2] 

如果您想從每個項目中獲得一個項目,但不是匹配項目,請執行

def dict_matcher(dict1, dict2, item1_pos, item2_pos, other1_pos, other2_pos): 

yield dict1[item1][other1_pos], dict2[item2][other2_pos] 

matches = list(dict_matcher(dict1, dict2 , 2, 6, 3, 8)) 

或什麼的,而不是3和8

如果你想獲得一些,但不是所有的項目,做

def dict_matcher(dict1, dict2, item1_pos, item2_pos, other1_poss, other2_poss): 

yield [dict1[item1][i] for i in other1_poss], [dict2[item2][i] for i in other2_poss] 

matches = list(dict_matcher(dict1, dict2 , 2, 6, (2, 3), (6, 8))) 

或任何代替[2,3]和[3,8]。

如果這不是你的意思,讓我知道。

+0

是的,謝謝你理解我這個令人困惑的問題! 'def dict_matcher(dict1,dict2,item1_pos,item2_pos,other1_pos,other2_pos)'正是我想要的,但是我正在嘗試使用'* args',這樣每次我調用該函數時,我都可以指定另一組other1_pos, other2_pos值。有時候我需要這樣的值:other1_pos1,other1_pos2,other2_pos3。其他時間我需要這樣的值:other1_pos3,other1_pos1,other2_pos6。可以*參數用於我想要做什麼? – drbunsen

+0

請參閱我答案中的最後一個。你不需要*參數。創建兩個列表 - 你想從字典1中得到的一個項目,你想從字典2中選擇的另一個項目。然後通過這些列表。這就是我在最後一個例子中所做的。它可以很好地處理你想要的任何數量的項目。請參閱最後一行代碼中的「(2,3)」和「(6,8)」?這些是你想要的列表。 – agf

+0

我最初並沒有意識到你最後一個例子正是我想要的。說真的,非常感謝你一直堅持跟我在一起。非常感謝您的回答。 – drbunsen

1

你可以使用slice objects

def dict_matcher(dict1, dict2, pos1, pos2, slicer1=(), slicer2=()): 
    slice1 = slice(*slicer1) if slicer1 else slice(len(dict1)) 
    slice2 = slice(*slicer2) if slicer2 else slice(len(dict2)) 
    for data1 in dict1.values(): 
     for data2 in dict2.values(): 
      if data1[pos1] == data2[pos2]: 
       yield data1[slice1], data2[slice2] 

for result1, result2 in dict_matcher(my_dict, your_dict, 2, 6, (3, 8, 2), (2, 6)): 
    print result1, result2 
  • some_list[slice(3, 8, 2)]相當於some_list[3:8:2], 給你的some_list開始與 第四個元素到第八元素每秒元素(其索引3)。
  • some_list[slice(2, 6)]相當於some_list[2:6],給 你開始與第三元件 (其具有索引2)一直到第六元件的some_list每個元素。
  • some_list[slice(7)]相當於some_list[:7],給你 some_list的每個元素直到第七個元素。

如果您省略參數slicer1/2,則函數假定您希望整個列表和切片都相應地設置。

此外,我刪除了不必要的字典查找。

+0

我從來沒有使用過一個切片對象。那很有意思。我真的很驚訝你理解他的問題。在閱讀你的答案後,我想我現在也瞭解它,哈哈。 – jdi

0

您正在尋找指定任意數量的索引對來嘗試比較匹配嗎?

這樣的事情?

def matcher(d1, d2, *args): 
    indexes = zip(args[0::2], args[1::2]) 
    for a, b in indexes: 
     for value1 in dict1.values(): 
      for value2 in dict2.values(): 
       x, y = value1[a], value2[b] 
        if x == y: 
         yield x, y 

dict1 = {1: ('frog', 'green'), 2: ('spider', 'blue'), 3: ('cricket', 'red')} 
dict2 = {a: ('frog', 12.34), b: ('ape', 22.33), c: ('lemur', 90.21)} 

matches = list(matcher(d1, d2, 
         0, 0, # first pair to search for matches 
         1, 1 # second pair, 
         # ... and so on, 
)) 

print matches 
# [('frog', 'frog')] 

我不認爲這是非常可用的,但這會做到這一點。如果由於切片的魔力而指定奇數個參數,這仍然會有所幫助。但是,正因爲如此,匹配器函數的接口將很容易錯誤地使用。

我會認真考慮更多的東西一樣:

def matcher(d1, d2, indexes_to_check): 
    ... 
print list(matcher(d1, d2, [(0, 0), (1, 1), ...])) 

def matcher(d1, d2, *indexes_to_check): 
    ... 
print list(matcher(d1, d2, (0, 0), (1, 1)))