2012-11-19 38 views
0

這是我的第一篇文章,我在編程方面很新,所以我可能無法適當地表達我的問題,但我會盡我所能!在Python中使用範圍作爲字典鍵,我有什麼選擇?

tries_dict = {1:'first', 2:'second', 3:'third', 4:'fourth', ub_tries:'last'} 

ub_tries = user input 

tries = 1 

input ('\nCome on make your ' + tries_dict.get(tries) + guess: ') 

這3個元素是一個猜數遊戲,我創建的一部分,我包括他們在tries += 1每個錯誤的答案後while循環。

正如你所看到的,在我的字典裏是第4個答案和最後可能的機會之前,遊戲就結束了,所以這裏的自定義值是什麼,我試圖做的:

我想找到一個在'第四'和'最後'之間獲得每個答案/關鍵字的'NEXT'值。

如:

tries = 5 

Come on make your next guess 

tries = 6 

Come on make your next guess 

我確實發現了一些複雜的循環方式,但被好奇的類型我想知道的更有效的/實際的方法來做到這一點。

這裏有一些選擇我想過,但不能得到工作:

  1. 使用範圍內的關鍵
  2. 尋找一種方法來產生4和ub_tries和使用之間有值的列表列表作爲鍵

因此,一般來說:如何創建一種方法來獲得未在字典中指定的鍵的一般答案(下一個或其他)?

任何反饋將不勝感激,隨時要求澄清,因爲我可以告訴自己我的問題是一種混亂。

我希望我在編程和提問相關問題上都能夠更加狡猾,到目前爲止,我的編程幾乎和我的總結技巧一樣混亂,感嘆!

+0

你只是想找:'tries_dict.get(試試,'下一個')'? – abarnert

+0

PS,你可以使用'range'作爲關鍵字(在Python 3中;在Python 2中,它是一個'xrange'),但我不明白這對你有什麼幫助。那麼你就必須使用'range'來做後續的查找,這會從哪裏來? – abarnert

+0

@abarnert我沒有真正明白dict.get的意思,沒有'下一個'的關鍵,所以我怎麼能得到它? 嗯,我確實考慮了範圍(5,ub_tries),這個範圍作爲'Next'值的鍵值。 – Newbie

回答

5

我不知道這是否是你想要的,但dict.get可能是答案:

>>> ub_tries = 20 
>>> tries_dict = {1:'first', 2:'second', 3:'third', 4:'fourth', ub_tries:'last'} 
>>> tries_dict.get(1, 'next') 
'first' 
>>> tries_dict.get(4, 'next') 
'fourth' 
>>> tries_dict.get(5, 'next') 
'next' 
>>> tries_dict.get(20, 'next') 
'last' 
>>> tries_dict.get(21, 'next') 
'next' 

當然,你可以在一個功能包裝這件事,以各種不同的方式。例如:

def name_try(try_number, ub_tries): 
    tries_dict = {1:'first', 2:'second', 3:'third', 4:'fourth', ub_tries:'last'} 
    return tries_dict.get(try_number, 'next') 

無論如何,dict.get(key, default=None)就像dict[key],但如果key是不是會員,而不是養KeyError,它返回default

至於你的建議:

使用範圍內的關鍵?

當然,你可以做到這一點(如果你在Python 2而不是3的時候,使用xrangerange),但如何將它幫助?

d = { range(1, 5): '???', 
     range(5, ub_tries): 'next', 
     range(ub_tries, ub_tries + 1): 'last' } 

這是完全合法的,但d[6]是要提出一個KeyError,因爲6是不一樣的東西range(5, ub_tries)

如果你想要這個工作,你可以建立一個RangeDictionary這樣的:

class RangeDictionary(dict): 
    def __getitem__(self, key): 
     for r in self.keys(): 
      if key in r: 
       return super().__getitem__(r) 
     return super().__getitem__(key) 

但是,這遠遠超出了「初學者蟒」,即使是這樣一個效率極其低下的,不完整的,非健壯的實現,所以我不會建議它。

尋找一種方法來生成使用該名單的一個關鍵

你是說像這樣4 ub_tries之間的值的列表?

>>> ub_tries = 8 
>>> tries_dict = {1:'first', 2:'second', 3:'third', 4:'fourth', ub_tries:'last'} 
>>> tries_dict.update({i: 'next' for i in range(5, ub_tries)}) 
>>> tries_dict 
{1: 'first', 2: 'second', 3: 'third', 4: 'fourth', 5: 'next', 6: 'next', 7: 'next', 8: 'last'} 
>>> tries_dict[6] 
'next' 

這可行,但它可能不是一個好的解決方案。

最後,你可以使用defaultdict,它可以讓你烤的默認值到字典,而不是將它作爲每個呼叫的一部分:

>>> from collections import defaultdict 
>>> tries_dict = defaultdict(lambda: 'next', 
...       {1:'first', 2:'second', 3:'third', 4:'fourth', ub_tries:'last'}) 
>>> tries_dict 
defaultdict(<function <lambda> at 0x10272fef0>, {8: 'last', 1: 'first', 2: 'second', 3: 'third', 4: 'fourth'}) 
>>> tries_dict[5] 
'next' 
>>> tries_dict 
defaultdict(<function <lambda> at 0x10272fef0>, {1: 'first', 2: 'second', 3: 'third', 4: 'fourth', 5: 'next', 8: 'last'}) 

但是請注意,這將永久創建每個元素第一你需要它的時候 - 你必須創建一個返回默認值的函數。這使得它更適用於要更新值的情況,並且只需要將缺省值作爲起點。

+0

def name_try(try_number,ub_tries):**爲什麼我們要定義name_try? – Newbie

+0

return tries_dict.get(try_number,'next')**表示'檢索'關鍵'try_number'的值,如果嘗試數字不是成員「檢索」默認在這種情況下被定義爲'下一個',對吧? 我可以在輸入語句中包含這個嗎?如: input('\ nCome on make your'+ tries_dict.get(tries_number,'next')+ guess:') – Newbie

+0

@Newbie:有時很好地包裝函數中的常用功能。例如,如果您需要從代碼中的30個位置獲取名稱,並且想要使用不同的實現進行操作,則具有一個函數意味着您只需要更改1行而不是30行。另外,在某些情況下,可以幫助代碼自行記錄。 – abarnert

1

我在這裏捕獲了您的遊戲意圖嗎?

max_tries = 8 

tries_verbage = { 
    1: 'first', 
    2: 'second', 
    3: 'third', 
    4: 'fourth', 
    max_tries: 'last' 
    } 

for i in xrange(1, max_tries + 1): 
    raw_input('Make your %s guess:' % tries_verbage.get(i, 'next')) 

回報

Make your first guess:1 
Make your second guess:2 
Make your third guess:3 
Make your fourth guess:4 
Make your next guess:5 
Make your next guess:6 
Make your next guess:7 
Make your last guess:8 
+0

哇這麼多新的東西學習!謝謝我做了一點小作業來更好地理解你的建議,所以...... raw_input = python 3.x中的輸入?我應該在我的情況下使用xrange還是範圍,爲什麼?我閱讀的內容是關於一些記憶的東西,但對於像我這樣的新手來說,它有點過於技術性。 %s基本上是一些字符串格式化的權利?在你的例子中它可以被翻譯爲:對於字符串中的給定範圍「插入」,在%s處,包括在字典中的所有值。 「加」「下一個」作爲其餘的值。除此之外,你的建議幫了我很多! thanx – Newbie

+0

@Newbie:是的,Python 3中的'input'在Python 2中被稱爲'raw_input',Python 3中的''range'在Python 2中被稱爲'xrange'。如果你正在學習Python 3,你不必現在擔心這一點 - 當然,除了必須閱讀人們爲Python 2編寫的答案之外。(在你的問題中添加'python3'標籤和/或提及Python版本將有助於解決這個問題。) – abarnert

1

你爲什麼不只是使用一個列表?

MAX_TRIES = 10 
tries_list = ["first", "second", "third", "fourth"] 

for word in (tries_list[:MAX_TRIES-1] + 
      (["next"] * (MAX_TRIES - len(tries_list) - 1)) + ["last"]): 
    result = raw_input("Come on, make your {} guess:".format(word)) 

注意按計劃進行MAX_TRIES = 0這個代碼將無法正常工作,但我不認爲這會是一個問題。

+0

謝謝, 可否請您詳細說明for語句? max_tries以前是用戶定義的,就像用戶輸入一樣,對不對? 試= 0 =第一?? 試= 1 =秒? ([「next」] *(max_tries - len(tries_list))**這個我根本沒有得到!,嘿嘿** 你能否給我提供一個「英文」一步一步解釋發生了什麼事那麼?:-p – Newbie

+0

'[「next」] *(max_tries-len(tries_list))'是'max_tries - len(tries_list)'列表的副本'「next」'。因此,如果'max_tries = 20'和'tries_list'是答案中顯示的9個元素的列表,它將有11個拷貝的字符串'「next」'。當你添加到9個元素'tries_list'時,你得到一個20個元素列表,其中前9個來自'tries_list',接下來的11個都來自''next「'。爲了得到_exactly_你想要的,你需要'max_tries - len(tries_list) - 1',然後加上'[「last」]'到最後。 – abarnert

+0

另外,這個循環並沒有給你當前嘗試的數字,只是字符串。但是如果你想要的話,看看內置的'枚舉'功能。你可以在'enumerate(tries_list ... + [「last」])中輸入',然後'i + 1'是當前嘗試的編號。 – abarnert

1

您可以使用字典,範圍爲關鍵:

def switch(x): 
return { 
    1<x<4: 'several', 
    5<x<40: 'lots' 
    }[1] 

def main(): 
x = input("enter no. of monsters ") 
print switch(x) 
return 0 

希望這有助於。 :)