在Python中反转堆栈

在Python中反转堆栈,python,stack,Python,Stack,要反转堆栈,请执行以下操作: 我做了一个空的临时堆栈 我使用了tempstack.push(stack.pop()) 然后将其重命名为stack=tempstack 但它似乎不起作用。知道为什么吗 要调用它,我只想使用reverse(stack),而不是stack=reverse(stack) 看起来您应该编写而不是堆栈。是否为空(): (编辑后)确定,现在不是stack=new\u stack,而是说return new\u stack。应使用stack=reverse(stack)调用该函数

要反转堆栈,请执行以下操作:

  • 我做了一个空的临时堆栈
  • 我使用了
    tempstack.push(stack.pop())
  • 然后将其重命名为
    stack=tempstack
  • 但它似乎不起作用。知道为什么吗

    要调用它,我只想使用
    reverse(stack)
    ,而不是
    stack=reverse(stack)


    看起来您应该编写
    而不是堆栈。是否为空():


    (编辑后)确定,现在不是
    stack=new\u stack
    ,而是说
    return new\u stack
    。应使用
    stack=reverse(stack)
    调用该函数


    (响应注释)如果返回值不是一个选项,那么我们需要知道有哪些方法可以修改堆栈对象。说出
    stack=new\u stack
    stack=stack()
    不会在函数之外更改它

    像这样的方法应该会奏效:

    def reverse(stack):
        new_stack = Stack()
        while not stack.is_empty():
            new_stack.push(stack.pop())
        stack._items = new_stack._items
    
    然而,这可能是个坏主意,因为
    \u items
    前面的下划线表明编写堆栈类的人不希望这样使用它


    另外,正如@user4815162342所指出的,这可能会使堆栈反转两次,因此我们不应该使用临时的
    new\u stack=stack()
    而应该使用临时列表。实际上@user4815162342的答案是最好的。

    看起来您应该编写
    而不是堆栈。is_empty():


    (编辑后)确定,现在不是
    stack=new\u stack
    ,而是说
    return new\u stack
    。应使用
    stack=reverse(stack)
    调用该函数


    (响应注释)如果返回值不是一个选项,那么我们需要知道有哪些方法可以修改堆栈对象。说出
    stack=new\u stack
    stack=stack()
    不会在函数之外更改它

    像这样的方法应该会奏效:

    def reverse(stack):
        new_stack = Stack()
        while not stack.is_empty():
            new_stack.push(stack.pop())
        stack._items = new_stack._items
    
    然而,这可能是个坏主意,因为
    \u items
    前面的下划线表明编写堆栈类的人不希望这样使用它

    另外,正如@user4815162342所指出的,这可能会使堆栈反转两次,因此我们不应该使用临时的
    new\u stack=stack()
    而应该使用临时列表。实际上@user4815162342的答案是最好的。

    添加一个返回值

    def reverse(stack):
        new_stack = Stack()
        while not stack.is_empty():
            new_stack.push(stack.pop())
        return new_stack
    
    调用函数时,请执行以下操作:

    stack = reverse(stack)
    
    您正在为函数内部的堆栈赋值,但不是从调用它的位置。范围问题。

    添加返回值

    def reverse(stack):
        new_stack = Stack()
        while not stack.is_empty():
            new_stack.push(stack.pop())
        return new_stack
    
    调用函数时,请执行以下操作:

    stack = reverse(stack)
    

    您正在为函数内部的堆栈赋值,但不是从调用它的位置。范围问题。

    如果您使用实际的
    列表
    来实现堆栈(即,如果
    堆栈
    继承自
    列表
    或基本上是一个列表),则只需将
    列表
    倒过来:

    def reverse_stack(stack):
        stack.reverse()
    
    为了避免混淆,我将函数重命名为
    reverse\u stack
    ;您仍然可以将其称为
    reverse
    。例如:

    >>> stack = [1, 2, 3]
    >>> reverse_stack(stack)
    >>> stack
    [3, 2, 1]
    
    但是,您的
    堆栈
    类似乎不是从
    列表
    继承的,而是将底层的
    列表
    保留在私有属性中,因此您不能在
    堆栈
    上直接使用任何
    可变序列
    API。因此,

    版本2,仅使用
    是空的
    推送
    弹出
    方法的
    堆栈
    仅使用
    Stack
    s,而不使用
    list
    s或
    deque
    s等。首先,使用两个助手函数:

    def reverse_copy_stack(stack, rev_stack=None):
        '''Return a reversed copy of stack, which is emptied.
        rev_stack receives the reversed copy if it's not None
        '''
        if rev_stack is None:
            rev_stack = Stack()
        while not stack.is_empty():
            rev_stack.push(stack.pop())
        return rev_stack
    
    def copy_stack(stack):
        '''Return a copy of stack, which is emptied.'''
        return reverse_copy_stack( reverse_copy_stack(stack))
    
    现在我们可以实现
    反向堆栈

    def reverse_stack(stack):
        '''Reverse stack in-place'''
        new_stack = copy_stack(stack)
        # Empty stack
        while not stack.is_empty():
            stack.pop()
        # put reversed copy of new_stack in stack
        reverse_copy_stack(new_stack, stack)
    

    如果您正在使用实际的
    list
    s来实现堆栈(即,如果
    Stack
    继承自
    list
    或基本上是一个列表),则只需将
    list
    倒过来:

    def reverse_stack(stack):
        stack.reverse()
    
    为了避免混淆,我将函数重命名为
    reverse\u stack
    ;您仍然可以将其称为
    reverse
    。例如:

    >>> stack = [1, 2, 3]
    >>> reverse_stack(stack)
    >>> stack
    [3, 2, 1]
    
    但是,您的
    堆栈
    类似乎不是从
    列表
    继承的,而是将底层的
    列表
    保留在私有属性中,因此您不能在
    堆栈
    上直接使用任何
    可变序列
    API。因此,

    版本2,仅使用
    是空的
    推送
    弹出
    方法的
    堆栈
    仅使用
    Stack
    s,而不使用
    list
    s或
    deque
    s等。首先,使用两个助手函数:

    def reverse_copy_stack(stack, rev_stack=None):
        '''Return a reversed copy of stack, which is emptied.
        rev_stack receives the reversed copy if it's not None
        '''
        if rev_stack is None:
            rev_stack = Stack()
        while not stack.is_empty():
            rev_stack.push(stack.pop())
        return rev_stack
    
    def copy_stack(stack):
        '''Return a copy of stack, which is emptied.'''
        return reverse_copy_stack( reverse_copy_stack(stack))
    
    现在我们可以实现
    反向堆栈

    def reverse_stack(stack):
        '''Reverse stack in-place'''
        new_stack = copy_stack(stack)
        # Empty stack
        while not stack.is_empty():
            stack.pop()
        # put reversed copy of new_stack in stack
        reverse_copy_stack(new_stack, stack)
    

    首先复制堆栈,清空原始堆栈,然后按照您的方法操作

    def reverse(stack):
        old_stack = stack[:]
        while not stack.is_empty():
            stack.pop()
        while not old_stack.is_empty():
            stack.push(old_stack.pop())
    

    首先复制堆栈,清空原始堆栈,然后按照您的方法操作

    def reverse(stack):
        old_stack = stack[:]
        while not stack.is_empty():
            stack.pop()
        while not old_stack.is_empty():
            stack.push(old_stack.pop())
    

    正如其他人所指出的,最后一项作业没有任何作用。然而,这里练习背后的想法可能是只使用标准堆栈原语
    push
    pop
    是空的
    ,而不依赖确切的堆栈实现来使用
    list.reverse

    需要注意的关键点是,堆栈是后进先出结构,因此读取其内容会自动以相反的顺序生成它们。这就是为什么使用另一个堆栈作为临时存储的解决方案不起作用的原因:

    def reverse(stack):
        # Doesn't work
        temp = Stack()
        while not stack.is_empty():
            temp.push(stack.pop())
        while not temp.is_empty():
            stack.push(temp.pop())
    
    在这里,堆栈内容被反转了两次:一次是从原始堆栈中读取,一次是从临时堆栈中读取,因此最终以原始顺序的堆栈内容结束。要实际反转堆栈,您需要将项目提取到列表中,然后按顺序(从开始到结束)遍历它,并在项目到达时将其推到原始堆栈上:

    def reverse(stack):
        items = []
        while not stack.is_empty():
            items.append(stack.pop())
        for item in items:
            stack.push(item)
    
    编辑:受BrianO回答的启发,这里有一个版本根本不使用列表(但实例化了两个临时堆栈):

    这里的想法是利用这样一个事实,即复制堆栈确实会反转内容-只是将其复制回会再次反转。所以我们就复制三个