LPTHW Excercise 48 Help - Работа с кортежами в списках - PullRequest
1 голос
/ 18 сентября 2011

Я сейчас прохожу LPTHW и у меня до упражнение 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')])

Этот вопрос задавался здесь раньше , и я заметил, что мое текущее решение до сих пор довольно идентично ответу , предоставленному 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

Таким образом, вопрос заключается в следующем: после ввода данных (слов), как правильно выполнить поиск в списке кортежей и затем вернуть определенный кортеж, частью которого он является?

Заранее благодарен за любые ответы и советы, действительно придерживайтесь этого.

Ответы [ 5 ]

3 голосов
/ 26 марта 2013

Вдохновленный первым решением @ 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 голосов
/ 06 мая 2017

Использование словаря сделает это намного проще и быстрее.Проверьте этот код

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
2 голосов
/ 19 сентября 2011

Так что благодаря подсказкам Томаса К & эда мне удалось выполнить упражнение.Теперь я был очень раздражен, теперь все было так просто, я смотрю на это ...

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
1 голос
/ 19 сентября 2011

Я не знаю, сколько было введено в упражнении 48, но у меня есть несколько комментариев к вашему решению выше.

Во-первых, с отдельной переменной для каждого списка слов, это немного сложносохранить этот код.Во-вторых, i обычно используется в качестве переменной только при подсчете натуральных чисел из 0.

. Рассмотрим:

_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 голосов
/ 18 сентября 2011

Предположительно, ваш список "направлений" в конечном итоге будет содержать кортежи с чем-то отличным от "направления" в качестве первой записи (после комментария @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)])

даст вам соответствующий кортеж.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...