如何为未排序列表编写pop(item)方法

时间:2012-12-07 22:00:09

标签: python data-structures

我正在实施一些基本数据结构以准备考试,并遇到了以下问题。我想实现一个未排序的链表,并且已经实现了一个pop()方法,但是我不知道,无论是在语法上还是在概念上,如何使函数有时会参与争论,有时候不会参与争论。我希望这是有道理的。

def pop(self):
    current = self.head
    found = False
    endOfList = None

    while current != None and not found:
        if current.getNext() == None:
            found = True
            endOfList = current.getData()
            self.remove(endOfList)
            self.count = self.count - 1
        else:
            current = current.getNext()

    return endOfList

我想知道如何使语句unsortedList.pop(3)有效,3只是一个例子,unsortedList是该类的新实例。

4 个答案:

答案 0 :(得分:3)

使用具有默认值的参数的基本语法(以及常见用例)如下所示:

def pop(self, index=None):
    if index is not None:
        #Do whatever your default behaviour should be

然后,您必须根据参数确定您希望如何更改行为。我只是猜测参数应该指定应从列表中弹出的元素的索引。

如果是这种情况,您可以直接使用有效的默认值,而不是None,例如0

def pop(self, index=0):

答案 1 :(得分:1)

首先,在函数中添加一个带默认值的参数:

def pop(self, item=None):

现在,在代码if item is None:中,您可以执行“无参数”操作;否则,请使用item。无论您想要切换到顶部还是降低逻辑,都取决于您的逻辑。在这种情况下,item is None可能意味着“匹配第一个项目”,因此您可能需要一个检查item is None or current.data == item:的循环。

有时您会想要为合法None的参数执行此操作,在这种情况下,您需要选择不同的哨兵。这里有一些问题(以及其他地方的博客文章)关于不同选择的利弊。但这是一种方式:

class LinkedList(object):
    _sentinel = object()
    def pop(self, item=_sentinel):

除非有人使用LinkedList的私有_sentinel类成员作为列表项,否则这是有效的。 (如果 有效 - 例如,因为你正在构建一个调试器 - 你必须变得更加棘手。)

这方面的术语有点棘手。引用文档:

  

当一个或多个顶级参数的格式为parameter = expression时,该函数会被称为“默认参数值”。

要理解这一点:“参数”(或“形式参数”)是定义函数的东西; “arguments”是在调用表达式中传递给函数的东西; “参数值”(或“实际参数”,但这只会使事情更加混乱)是函数体接收的值。因此,在技术上不正确地引用“默认参数”或“带有默认参数的参数”,但两者都很常见,因为即使专家也发现这些东西令人困惑。 (如果您感到好奇,或者感到困惑,请参阅参考文档中的function definitionscalls以获取完整的详细信息。)

答案 2 :(得分:0)

您的考试是否专门使用Python?如果没有,您可能需要查看function overloading. Python不支持此功能,但许多其他语言都支持此功能,并且是解决此类问题的常用方法。

在Python中,你可以通过使用默认值的参数获得很多好处(正如Michael Mauderer的例子所指出的那样)。

答案 3 :(得分:0)

def pop(self, index=None):
    prev = None
    current = self.head
    if current is None:
       raise IndexError("can't pop from empty list")
    if index is None:
       index = 0 # the first item by default (counting from head)

    if index < 0:
       index += self.count
    if not (0 <= index < self.count):
       raise IndexError("index out of range")

    i = 0
    while i != index:
        i += 1
        prev = current
        current = current.getNext()
        assert current is not None # never happens if list is self-consistent

    assert i == index
    value = current.getData()
    self.remove(current, prev)
    ##self.count -= 1 # this should be in self.remove()
    return value