2011-09-18 20 views
1

我目前正在通過LPTHW,我達到excercise 48,這是我第一次碰到磚牆。LPTHW Excercise 48幫助 - 在列表中使用元組

這裏的測試用例的第一部分,我一直在考慮

from nose.tools import * 
from ex48 import lexicon 

def test_direction(): 
    assert_equal(lexicon.scan("north"), [('direction', 'north')]) 
    result = lexicon.scan("north south east") 
    assert_equal(result, [('direction', 'north'), 
          ('direction', 'south'), 
          ('direction', 'east')]) 

This question has been asked here before,我注意到我目前的解決方案,到目前爲止是相當一致的answer provided by robbyt。但它仍然不起作用。

def scan(thewords): 

    directions = [('direction', 'north'), ('direction', 'south'), ('direction', 'east')] 

    thewords = thewords.split() 
    sentence = [] 

    for i in thewords: 
     if i in directions: 
      sentence.append(('direction', i)) 

     else: 
      sentence.append(('error', i)) 


    return sentence 

因此問題是:以輸入(thewords)後,我怎麼過的元組列表中搜索正確,然後返回特定的元組是的一部分嗎?

在此先感謝任何排序的答案和建議,真的堅持這一個。

+0

想想你需要'方向'來保存你的功能。是否需要三次保持「方向」文字? –

+0

謝謝,看起來好像我只是在爲自己複雜的事情。我只是簡單地將它改爲僅包含第二個元素的列表,並使其工作。 – Dairylee

回答

2

所以,感謝Thomas K & ed的提示,我設法完成了這個練習。與自己相當惱火了,現在一切都是那麼簡單我看它......

directions = ['north', 'south', 'east', 'west', 'down', 'up', 'down', 'right'] 
verbs = ['go', 'stop', 'kill', 'eat'] 
stops = ['the', 'in', 'at', 'of', 'from', 'at', 'it'] 
nouns = ['door', 'bear', 'princess', 'cabinet'] 


def scan(thewords): 

    thewords = thewords.split() 
    sentence = [] 

    for i in thewords: 
     if i in directions: 
      sentence.append(('direction', i)) 

     elif i in verbs: 
      sentence.append(('verb', i)) 

     elif i in stops: 
      sentence.append(('stop', i)) 

     elif i in nouns: 
      sentence.append(('noun', i)) 

     elif i.isdigit(): 
      sentence.append(('number', convert_number(i))) 

     else:    
      sentence.append(('error', i)) 

    return sentence 

def convert_number(s): 
    try: 
     return int(s) 

    except ValueError: 
     return None 
0

假設你的「方向」列表最終將包含除「方向」之外的元組作爲第一個條目的元組(下面來自@Thomas K的評論)。

如果您只是你的元組的第二個元素的列表:

valid_words = [x[1] for x in directions] 

然後修改你的代碼,這樣做:

for i in thewords: 
    if i in valid_words: 
     sentence.append(directions[valid_words.index(i)]) 

會給你相關的元組。

+0

感謝您的迴應,但事實證明,我只是爲了自己而讓事情過於複雜。我感謝你的回答,如果我發現自己需要在將來這樣做,我會記住它。 這也是我第一次看到寫在[]括號中的for循環,就像寫作一樣... 'for x in directions' 'valid_words = [x [1]] ' ? – Dairylee

+0

這是一個「列表理解」(http://docs.python.org/glossary.html#term-list-comprehension)。這是處理序列(列表,元組,字符串等)並輸出列表的快速方法。額外的「if」參數特別有用,儘管在本例中我沒有使用它。 –

1

我不知道有多少已經被鍛鍊48出臺,但我上面有您的解決方案几點意見。

首先,每個單詞列表都有一個單獨的變量,維護此代碼有點困難。其次,當從0開始計算自然數時,i通常僅用作變量。

考慮:

_LEXICON = dict(
    direction = ['north', 'south', 'east', 'west', 'down', 'up', 'down', 'right'], 
    verb = ['go', 'stop', 'kill', 'eat'], 
    stop = ['the', 'in', 'at', 'of', 'from', 'at', 'it'], 
    noun = ['door', 'bear', 'princess', 'cabinet'], 
    number = ['0','1','2','3','4','5','6','7','8','9'], 
) 

def scan(words): 
    result = [] 

    for word in words.split(): 
     found_category = 'error' 
     for category, category_lexicon in _LEXICON.items(): 
      if word in category_lexicon: 
       found_category = category 
       break 

     result.append((found_category, word)) 

    return result 

但我們可以做的更好;在列表中尋找物品很慢。當你想看一些東西時,你想要一本字典:

_LEXICON = dict(...) 
_LEXICON_INDEX = dict() 
for category, words in _LEXICON: 
    for word in words: 
     _LEXICON_INDEX[word] = category 

def scan(words): 
    result = [] 

    for word in words.split(): 
     result.append((_LEXICON_INDEX.get(word, 'error'), word)) 

    return result 

當然,這並沒有通過練習中的所有測試。我會留給你解決我的代碼。 ;)

+0

感謝你的明天,我將在明天發佈一篇文章,看看我是否可以用字典來代替它。 – Dairylee

3

受@ Evee的第一個解決方案(謝謝)的啓發,這是我的解決方案,通過所有測試。也許它使用比第二種解決方案更多的代碼,但它消除了定義的唯一方法之外的循環。

class Lexicon(object): 
    def __init__(self): 
     self.mapping = { 
       'direction': ['north', 'south', 'east', 'west'], 
       'verb':  ['go', 'kill', 'eat'], 
       'stop':  ['the', 'in', 'of'], 
       'noun':  ['door', 'bear', 'princess', 'cabinet'] 
       } 
     self.mapping_categories = self.mapping.keys() 

    def scan(self, input): 
     self.result = [] 

     for word in input.split(): 
      try: 
       self.result.append(('number', int(word))) 
      except ValueError: 
       for category, item in self.mapping.items(): 
        if word.lower() in item: 
         found_category = category 
         break 
        else: 
         found_category = 'error' 
       self.result.append((found_category, word)) 

     return self.result 

lexicon = Lexicon() 
2

使用字典會使它更容易和更快。 查看本代碼

directions = ['north', 'south', 'east', 'west', 'down', 'up', 'left', 'right', 'back'] 
verbs = ['go','stop','kill','eat'] 
stop_words = ['the', 'in', 'of', 'from', 'it'] 
nouns = ['door','bear','princess','cabinet'] 

lexicons = {} 
for key in directions: 
    lexicons[key] = 'direction' 
for key in verbs: 
    lexicons[key] = 'verb' 
for key in stop_words: 
    lexicons[key] = 'stop' 
for key in nouns: 
    lexicons[key] = 'noun' 

def scan(sentence): 
    tuples = [] 
    words = sentence.split() 
    for word in words: 
     try: 
      tuples.append((lexicons[word],word)) 
     except KeyError: 
      if word.isdigit(): 
       tuples.append(('number',int(word))) 
      else: 
       tuples.append(('error',word)) 
    return tuples