2016-11-13 67 views
0

我需要分析的字典對於包括兩個給定數字之間的數(作爲參數)值之間的值的密鑰,並返回通過鍵搜索在字典具有兩個數

字典前面那些值:

{'P':[("Eight",1460, 225.0, 200.0, "fresco","Netherlands"),("Six",1465,81.0, 127.1, "tempera", "Netherlands")], 
     'V':[("Four",1661, 148.0, 257.0,"oil paint", "Austria"),("Two",1630, 91.0, 77.0, "oil paint","USA")], 
     'K':[("Five",1922,63.8,48.1,"watercolor","USA"),("Seven",1950,61.0,61.0,"acrylic paint","USA"),("Two",1965,81.3,100.3,"oil paint","United Kingdom")], 
     'C':[("Ten",1496,365.0,389.0,"tempera","Italy")], 
     'U':[("Nine",1203,182.0, 957.0,"egg tempera","Italy"), ("Twelve",1200,76.2,101.6,"egg tempera","France")] 
     } 

函數應該只返回兩個數之間的數字存在的值。因此,如果函數被調用between_two_values應該如果1464和1496之間尋找值返回此:

between_two_values(dictionary1(), 1464, 1496) 

{'P': [('Six', 1465, 81.0, 127.1, 'tempera',  
'Netherlands')], 'C': [('Ten', 1496, 365.0, 
389.0, 'tempera', 'Italy')]} 

如果鍵的值的一個不具備1464年至1496年之間的數字,它不應該返回一個值並且只有在該範圍內具有數字的那些數字之前有其密鑰。這就是爲什麼在上面的'P'的例子中,有1460的第一個值沒有返回,因爲它不在2個數字之間。如果第一個數字大一些,函數中的第一個數字應該總是小於第二個數字,然後它應該只返回一個空字典。

這是我想出的代碼我不認爲它是正確的,但它顯示可以解決此功能的邏輯。我感謝我收到的任何幫助

def between_two_values(dictionary,start,end): 
    for x in dictionary: 
     if end < x < start in dictionary: 
      return dictionary(x) 
+0

你運行你的這個代碼對詞典嗎?任何錯誤消息顯示? –

+0

@melgart現在它說類型錯誤:無法訂購的類型:int() n00bprogrammer22

+2

很酷,這很有用。它是說你正在試圖比較蘋果和橘子。好像你不確定你在between_two_values()函數中比較的是什麼。你爲什麼不考慮在for循環之後在那裏放入一些print()語句,這樣你就可以看到你正在迭代的數據。請記住,Python字典有映射到值的鍵,你可以像這樣訪問字典:dictionary [x] –

回答

0

您正確的道路上。這是解決問題的一個解決方案。

爲了清晰起見,我更好地格式化了數據。當它被壓縮下來時,我並沒有立即看到每個字典值被包裹在一個列表中。當然這是一種面向風格的改變,但風格有助於可讀性。

請注意,我已經做了一些假設,例如每個字典值將是一個列表。例如,您沒有值的密鑰的邊緣情況將表示爲[]而不是None。我也推斷了我認爲期望的輸出來自您給出的例子。最後,您可以考慮使用collections.defaultdict來簡化存儲匹配的位置。

除此之外,這段代碼沒什麼特別。你當然可以更多地壓縮它,或者使用類來進行語義學。說到語義,我建議你使用比我更好的變量名稱:「數據」,「記錄」和「值」是非常通用的,但我覺得他們幫助解釋解決方案,而我沒有洞察這些數據代表什麼。

如果您使用Python 2中,考慮使用的dictionary.iteritems()代替dictionary.items()

數據

data = { 
    'P': [ 
     ('Eight', 1460, 225.0, 200.0, 'fresco', 'Netherlands'), 
     ('Six', 1465, 81.0, 127.1, 'tempera', 'Netherlands'), 
    ], 
    'V': [ 
     ('Four', 1661, 148.0, 257.0, 'oil paint', 'Austria'), 
     ('Two', 1630, 91.0, 77.0, 'oil paint', 'USA'), 
    ], 
    'K': [ 
     ('Five', 1922, 63.8, 48.1, 'watercolor', 'USA'), 
     ('Seven', 1950, 61.0, 61.0, 'acrylic paint', 'USA'), 
     ('Two', 1965, 81.3, 100.3, 'oil paint', 'United Kingdom'), 
    ], 
    'C': [ 
     ('Ten', 1496, 365.0, 389.0, 'tempera', 'Italy'), 
    ], 
    'U': [ 
     ('Nine', 1203, 182.0, 957.0, 'egg tempera', 'Italy'), 
     ('Twelve', 1200, 76.2, 101.6, 'egg tempera', 'France'), 
    ], 
} 

代碼

def between_two_values(dictionary, start, end): 
    matches = {} 
    for key, record_list in dictionary.items(): 
     for record in record_list: 
      value = record[1] 
      if start < value < end: 
       if key in matches: 
        matches[key].append(record) 
       else: 
        matches[key] = [record] 
    return matches 

result = between_two_values(data, 1464, 1496) 
print(result) 

輸出

{'P': [('Six', 1465, 81.0, 127.1, 'tempera', 'Netherlands')]} 
+0

你知道你可以寫:'如果開始<值<結束:' – AChampion

+0

@AChampion更新以反映這一點。謝謝。 –

+0

謝謝有沒有辦法返回結果而不是打印它?它在打印時起作用,但當我改變它返回時ays返回外部函數 – n00bprogrammer22

0

可以使用dict理解,構建結果,例如:

>>> {k: [e for e in v if 1464 < e[1] < 1496] for k, v in dictionary.items()} 
{'C': [], 
'K': [], 
'P': [('Six', 1465, 81.0, 127.1, 'tempera', 'Netherlands')], 
'U': [], 
'V': []} 

然後就消除了空的結果:

def between_two_values(dictionary, start, end): 
    result = {k: [e for e in v if start < e[1] < end] for k, v in dictionary.items()} 
    return {k: v for k, v in result.items() if v} 
+0

不錯,簡潔。 –

+0

你可以結合使用這個技巧:'{k:f for k,v in dictionary.items()for f in([e for e in v如果start

+0

是的,明白你可以做到這一點,但是在簡潔性,可理解性和性能之間有一個平衡點。考慮到OPs處理@ n00bprogrammer22,我錯誤地在更冗長的一面,希望它更容易訪問:)。我可以使用'result'的元組生成器來避免字典構造,但我不是一個過早(在優化中)。 – AChampion