在Python中编写手动弹出函数

时间:2018-02-08 00:28:28

标签: python python-3.x

在我开始之前:

import sys
sys.ps1 = "<?>> "

行。 作为一名C级程序员,我不禁以任何方式保持敏锐(使用我选择的任何语言),而是通过编写低级程序。今天,一个问题来自于Python3中一个非常简单的例子。

当一个小的pop()写入Stack类时,我收到了一些好奇的输出。

class Stack():

    def __init__(self, data):
        self.stack = [i for i in data]
        self.size = int(len(self.stack))

    def pop(self):
        ch = self.stack[self.size - 1]
        del(self.stack[-1])
        self.size = self.size - 1
        return ch


msg = Stack("Hello!")
for i in msg.stack:
    print(m.pop(), end="")

<?>> !ol

for i in msg.stack:
    print(m.pop(), end="")

<?>> le

for i in msg.stack:
    print(m.pop(), end="")

<?>> H

print(msg.stack)

<?>> []

如你所见,弹出并输出整个列表需要3个循环['H','e','l','l','o']; 3个字符,然后是2个,然后是1个,但列表会相应耗尽吗?更长的输入需要更多的循环。这里有什么抑制因素?

1 个答案:

答案 0 :(得分:2)

问题基本上是您在修改容器时迭代容器。可以这样考虑,在内部,list迭代器只是继续推进索引,直到它达到IndexError。由于您修改了列表,因此它会在您删除3个元素之后点击IndexError,因为它会尝试my_list[3]len(my_list) == 3。有几种方法可以解决这个问题。第一种,在这种情况下只使用while循环:

In [4]: class Stack:
   ...:
   ...:     def __init__(self, data):
   ...:         self.stack = [i for i in data]
   ...:         self.size = int(len(self.stack))
   ...:
   ...:     def pop(self):
   ...:         ch = self.stack[self.size - 1]
   ...:         del(self.stack[-1])
   ...:         self.size = self.size - 1
   ...:         return ch
   ...:     def __len__(self):
   ...:         return self.size
   ...:

In [5]: stack = Stack("Hello!")

In [6]: while stack:
   ...:     print(stack.pop(), end='')
   ...:
!olleH

注意,我定义了__len__方法,以便while stack:可以直接使用,而不是while stack.size:

你也可以想象一下,只需在范围对象上循环:

In [7]: stack = Stack("Hello!")

In [8]: for _ in range(len(stack)):
   ...:     print(stack.pop(), end='')
   ...:
!olleH

更棘手:在反向方向循环!由于您从最后开始弹出,因此IndexError开始在list_reverseiterator开始编制索引,直到alist[len(alist) - 1]为止,因此您无法获得alist[0]。我可能不会依赖这种行为感到舒服,但它有记录,并且确实有效:

In [9]: stack = Stack("Hello!")

In [10]: for _ in reversed(stack.stack):
    ...:     print(stack.pop(), end='')
    ...:
!olleH
In [11]:

最后,尝试并且真实:循环副本

In [11]: stack = Stack("Hello!")

In [12]: for _ in stack.stack[:]: #whole slice copies
    ...:     print(stack.pop(), end='')
    ...:
!olleH