2014-02-10 2 views
2

내가 파이썬 어려운 방법 알아보기 행사 (48) 작업과 lexicon 사전과에 다음과 같은 시험을 실행하는 scan 모듈을 쓰고 있어요 :이 체격의 대부분이"개방형"사전 키? (LPTHW 운동 관련 48)

from nose.tools import * 
from ex47 import lexicon 


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

def test_verbs(): 
    assert_equal(lexicon.scan("go"), [('verb', 'go')]) 
    result = lexicon.scan("go kill eat") 
    assert_equal(result, [('verb', 'go'), 
          ('verb', 'kill'), 
          ('verb', 'eat')]) 


def test_stops(): 
    assert_equal(lexicon.scan("the"), [('stop', 'the')]) 
    result = lexicon.scan("the in of") 
    assert_equal(result, [('stop', 'the'), 
          ('stop', 'in'), 
          ('stop', 'of')]) 


def test_nouns(): 
    assert_equal(lexicon.scan("bear"), [('noun', 'bear')]) 
    result = lexicon.scan("bear princess") 
    assert_equal(result, [('noun', 'bear'), 
          ('noun', 'princess')]) 

def test_numbers(): 
    assert_equal(lexicon.scan("1234"), [('number', 1234)]) 
    result = lexicon.scan("3 91234") 
    assert_equal(result, [('number', 3), 
          ('number', 91234)]) 


def test_errors(): 
    assert_equal(lexicon.scan("ASDFADFASDF"), [('error', 'ASDFADFASDF')]) 
    result = lexicon.scan("bear IAS princess") 
    assert_equal(result, [('noun', 'bear'), 
          ('error', 'IAS'), 
          ('noun', 'princess')]) 

을 숫자 및 오류 테스트를 제외하고 사용자 입력이 사전에 정의되지 않은 단어 인 경우 error 값 이름과 숫자 인 경우 number 값 이름으로 태그를 지정해야합니다. 분명히 사전에 테스트 할 모든 입력을 사전에 추가 할 수는 있지만 그건 치욕적입니다.

내 사전은 다음과 같습니다

lexicon = { 
    'north': 'direction', 
    'princess': 'noun', 
    # etc... 
} 

작동하는 방법, 어,이에 숫자와 정의되지 않은 단어 "개방적"정의가 있습니까?

업데이트.

def scan(sentence): 
    words = sentence.split() 
    pairs = [] 

    for word in words: 
     try: 
      number = int(word) 
      tupes = ('number', number) 
      pairs.append(tupes) 

     except ValueError: 
      try: 
       word_type = lexicon[word] 
       tupes = (word_type, word) 
       pairs.append(tupes) 
      except KeyError: 
       tupes = ('error', word) 
       pairs.append(tupes) 
    return pairs 
+0

귀하의 솔루션은 좋아 보인다. 그것을 개선하는 방법을 제안 할 수 있습니다 : 가능한 한 적은 수의 줄을 "try"블록에 넣고 예외가 발생하지 않을 때 어떻게해야하는지에 대한 "else"블록을 추가하십시오. 이렇게하면 코드 중복을 줄일 수 있으며 더 중요한 것은 사용자의 의도를 독자에게 알릴 수 있습니다.다음은 try/except/else를 설명하는 이유와 그 이유를 설명하는 좋은 질문입니다. http://stackoverflow.com/questions/16138232/is-it-a-good-practice-to-use-try-except-else -in-python –

답변

0

귀하의 항목이 사전에 있는지 여부를 확인하여이 "개방성"을 찾을 수있을 것입니다. 이런 식으로 뭔가가 작동합니다 : 사전 lexicon 그렇지 않으면 my_item의 키를 포함하고, 거짓 경우 True를 반환

my_item in lexicon 

.

하지만 더 좋은 방법이 있습니다.

이것은 "허가보다 용서를 구하는 것이 더 낫습니다"라는 Python 개념을 실습 할 수있는 좋은 기회입니다. 어떻습니까?

try: 
    value = lexicon[my_item] 
except KeyError: 
    # KeyError is thrown when you index into a dictionary with a nonexistent key 
    value = 'error' 

동시에 우연히도 문자열을 정수로 변환 할 수 있는지 여부를 확인할 수 있습니다.

try: 
    value = int(maybe_a_number) 
except ValueError: 
    # maybe_a_number wasn't a number! 

이것은 파이썬에서 일반적인 패턴입니다. 특정 방식으로 변수를 사용하고 실패 사례를 처리하려고합니다.

사전에 대한 자세한 자료를 들어, 체크 아웃 : http://docs.python.org/2/library/stdtypes.html#mapping-types-dict

+0

이 경우 기본값을 사용하는 것이 훨씬 더 좋습니다. 'value = lexicon.get (my_item, "error")' – Daenyth

+0

@Daenyth 어떻게 그렇게? – sivanes

4

당신은 선택 사양 기본 인수와 함께 사전의 get 메소드를 사용할 수 있습니다 : 여기에 작동하는 솔루션입니다

파이썬 키를 확인하기 위해 루프를 제외하고/시도 사용하기에 또한 일반적입니다
d = {"a":'letter', 4:'number'} 
result = d.get("not in d", 'error') 
print result 
# error 

오류가 발생하지만이 경우에는 과도한 공격 일 수 있습니다.

d = {"a":'letter', 4:'number'} 
try: 
    result = d['not in d'] 
except KeyError: 
    result = 'error' 
print result 
# error 

나는 캐릭터가 훨씬 위의 두 번째 예와 같이, 하나 플로트를 사용하거나 블록을 제외하고 시도 내에서 int로입니다 파이썬에 숫자 인 경우 가장 쉬운 방법은 체크 생각합니다. 어느 것을 사용하는지는 "1.2"및 "3.4e5"를 숫자로 간주할지 여부에 따라 다릅니다.