Альтернатива «назначить вызову функции» в питоне - PullRequest
0 голосов
/ 26 марта 2012

Я пытаюсь решить эту загадку для новичка:

Я создал эту функцию:

def bucket_loop(htable, key):
    bucket = hashtable_get_bucket(htable, key)
    for entry in bucket:
        if entry[0] == key:          
            return entry[1]                         
    return None

И я должен вызвать ее в двух других функциях (ниже) вследующим образом: изменить значение элемента entry [1] или добавить в этот список (запись) новый элемент.Но я не могу сделать это, вызывая функцию bucket_loop так, как я это сделал, потому что «вы не можете назначить вызов функции» (назначение в вызов функции недопустимо в Python).Какая альтернатива (наиболее похожая на код, который я написал) для этого (bucket_loop (htable, key) = value и hashtable_get_bucket (htable, key) .append ([key, value]))? *

def hashtable_update(htable, key, value):
    if bucket_loop(htable, key) != None:
        bucket_loop(htable, key) = value
    else:
        hashtable_get_bucket(htable, key).append([key, value])

def hashtable_lookup(htable, key):
    return bucket_loop(htable, key)

Заранее спасибо за любую помощь!

Это остальная часть кода, чтобы этот скрипт работал:

def make_hashtable(size):
    table = []
    for unused in range(0, size):
        table.append([])
    return table

def hash_string(s, size):
    h = 0
    for c in s:
         h = h + ord(c)
    return h % size

def hashtable_get_bucket(htable, key):
    return htable[hash_string(key, len(htable))]

Аналогичный вопрос (но он мне не помог): SyntaxError: «невозможно назначить вызов функции»

Ответы [ 3 ]

2 голосов
/ 26 марта 2012

В общем, вы можете сделать три вещи:

  1. Запись функций «установки» (напр., bucket_set)
  2. Возвращает изменяемые значения (например, bucket_get(table, key).append(42), если значение равно list)
  3. Используйте класс, который переопределяет __getitem__ и __setitem__

Например, у вас может быть такой класс, как:

class Bucket(object):
    def __setitem__(self, key, value):
        # … implementation …
    def __getitem__(self, key):
        # … implementation …
        return value

Тогда используйте это так:

>>> b = Bucket()
>>> b["foo"] = 42
>>> b["foo"]
42
>>> 

Это был бы самый Pythonic способ сделать это.

1 голос
/ 26 марта 2012

Одним из вариантов, который потребует несколько изменений, будет добавление третьего аргумента в bucket_loop, необязательный, для использования в присваивании:

empty = object() # An object that's guaranteed not to be in your htable
def bucket_loop(htable, key, value=empty):
    bucket = hashtable_get_bucket(htable, key)
    for entry in bucket:
        if entry[0] == key:
           if value is not empty: # Reference (id) comparison
                entry[1] = value
            return entry[1]
        else: # I think this else is unnecessary/buggy
            return None

Однако несколько указателей:

  1. Я согласен с Игнасио Васкесом-Абрамсом и Дэвидом Волевером, класс был бы лучше;

  2. Поскольку в ведре может быть более одной пары ключ / значение, вы не должныt вернет None, если первая запись не соответствует вашему ключу.Переберите их всех и верните только None в конце;(вы также можете опустить это утверждение, поведение по умолчанию должно возвращать None)

  3. Если ваш htable не принимает None в качестве значения, вы можете использовать его вместо empty.

0 голосов
/ 26 марта 2012

Итак, вы в основном обманываете udacity, который является онлайн-классом / университетом CS?Самое смешное, что вы не могли даже правильно сформулировать вопрос.В следующий раз тщательно читайте и вставьте две функции, которые вы должны упростить, и попросите кого-нибудь упростить их, создав третью функцию с перекрывающимся кодом внутри.В любом случае это не имеет значения, потому что если вам нужна помощь, вероятно, вы не очень хорошо справляетесь с классом

, вы также смогли решить проблему, не используя большинство из этих инструментов, это былоупражняйтесь в понимании того, как определить избыточность дескриптора, а НЕ эффективность ...

Реальные инструкции:

Измените код для hashtable_update и hashtable_lookup, чтобы иметь то же поведение, что и сейчас, но используя меньшестроки кода в каждой процедуре.Вы должны определить новую процедуру, помощник, чтобы помочь с этим.Ваша новая версия должна иметь примерно то же время выполнения, что и исходная версия, но ни hashtable_update, ни hashtable_lookup не должны содержать цикл for или while, а блок каждой процедуры должен содержать не более 6 строк кода

Серьезно, измена хромает.

...