2012-03-26 49 views
0

我试图解决这个新手的难题:替代“指定给一个函数调用”在Python

我创造了这个功能:

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

我必须把它在两个其他函数(波纹管)按以下方式:更改元素条目[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: "can't assign to function call"

+0

你有没有考虑过把它作为一个类并定义'__getitem __()'和'__setitem __()'? – 2012-03-26 05:18:22

+1

我有点不清楚你的第一个代码。你有一个if else语句的循环,所以它只会执行一个循环。你只想检查桶中的第一个元素,还是要检查桶中的所有元素? – Jeff 2012-03-26 05:26:31

+0

嗨伊格纳西奥巴斯克斯 - 艾布拉姆斯,我不假设在这个过程中使用类(我还没有学会这个概念)。但非常感谢你的提示。 – craftApprentice 2012-03-26 12:43:04

回答

2

在一般情况下,有三件事情可以做:

  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 
>>> 

这将是最Python的方式来做到这一点。这将需要一些变化

+0

谢谢,大卫,最好的表达!我仍然怀疑如何改变列表的值(在这种情况下,entry [1]是一个列表),像这样的“bucket_loop(htable,key)= value”,但你的建议帮助了我。而不是bucket_loop(htable,key)返回条目[1],它现在返回条目(这也是一个列表),并且我用hashtable_update(htable,key,value)的方式为这个条目分配了一个新值:“entry [1] =值“。但如果有办法做到这一点返回入口[1](而不是进入),它会更好)。 – craftApprentice 2012-03-26 13:23:04

+0

如果'bucket_lookup'返回一个列表(你也可以,比如说'bucket_lookup(htable,key).name =“John”''bucket_lookup(htable,key)[0] = 42' '返回了一个'​​人')。这是因为,在这种情况下,您正在分配给* bucket_lookup所返回的对象的一个​​字段,因此您没有将*直接分配给对象*。 – 2012-03-26 16:51:36

1

一个办法是增加了第三个参数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. 由于存储桶可以有多个键/值对,因此如果第一个条目与您的键不匹配,则不应该返回无。循环遍历它们,最后只返回None; (你也可以省略这个声明,默认行为是返回None)

  3. 如果你的htable不允许None作为一个值,你可以用它来代替empty

-1

所以你基本上在udacity作弊,这是一个在线cs类/大学?有趣的是你甚至无法正确地声明问题。下一次彻底欺骗并粘贴你应该简化的两个函数,并请求某人通过创建第三个函数并使用其中的重叠代码来简化它们。无论如何,无论如何,因为如果这是你需要帮助的人在课堂上可能表现不佳,你可以在课堂上做得不是很好。

你也可以在不使用大多数这些工具的情况下解决问题,这是一个练习了解如何识别手柄冗余,而不是效率...

真实的说明:

修改都hashtable_update和hashtable_lookup代码有他们现在都有相同的行为,但使用更少的代码在每道工序。你应该定义一个新的程序,助手,来帮助解决这个问题。您的新版本应该与原始版本具有大致相同的运行时间,但散列表更新或hashtable_lookup都不应包含任何for或while循环,并且每个过程的代码块不得超过6行代码

严重的是,作弊是跛脚的。

+0

你能提供这个指控的证据吗? – 2012-03-26 16:52:32

相关问题