简单的列表和普通函数
如果您只需要实现一个堆栈,我认为没有理由使用collections.deque。我们可以轻松地围绕一个简单的列表构建,[] -
# stack.py
def empty():
return []
def push(t, x):
t.append(x)
def pop(t):
return t.pop()
def load(t, iterable):
for x in iterable:
push(t, x)
def unload(t):
while t:
yield pop(t)
使用堆栈很直观-
# main.py
import stack
input = "we have not defeated corona"
s = stack.empty()
stack.load(s, input)
output = "".join(stack.unload(s))
print(output)
anoroc detaefed ton evah ew
让它更像 python
如果您希望stack 具有更面向对象的感觉,我们可以在普通函数周围添加一个接口 -
# stack.py (continued)
class stack:
def empty(): return stack(empty())
def __init__(self, t): self.t = t
def push(self, v): return push(self.t, v)
def pop(self): return pop(self.t)
def load(self, iterable): return load(self.t, iterable)
def unload(self): return unload(self.t)
现在我们可以写main如下-
# main.py
from stack import stack
input = "we have not defeated corona"
s = stack.empty()
s.load(input)
output = "".join(s.unload())
print(output)
anoroc detaefed ton evah ew
扩展堆栈模块
继续往 Stack 模块添加其他功能 -
# stack.py (continued)
def reverse(t):
t.reverse()
def peek(t):
if not t:
return None
else:
return t[-1]
在面向对象的界面中包装你的新函数 -
# stack.py (continued)
class stack:
def empty(): ...
def __init__(): ...
def push(): ...
def pop(): ...
def load(): ...
def unload(): ...
def reverse(self): return reverse(self.t) # <-
def peek(self): return peek(self.t) # <-
让我们验证 seek 和 reverse 是否正常工作 -
# main.py
from stack import stack
input = "we have not defeated corona"
s = stack.empty()
s.load(input)
print(s.peek())
s.pop()
print(s.peek())
s.reverse()
print(s.peek())
a
n
w
相关阅读
在recent Q&A 中,我展示了如何设计类似于上述stack 的模块。如果您想了解随着程序的发展如何应用此技术,我鼓励您查看该帖子:D
持久堆栈
作为一个有趣的练习,我们可以在不使用deque、list 或任何其他内置数据容器的情况下实现堆栈。相反,我们将使用普通的None 和匿名函数。我分享这个例子是为了让你意识到程序员可以在他们的想象中构建任何东西,即使你使用的语言不包含特定的功能 -
# stack.py
empty = None
def push(t, v):
return lambda k: k(t, v)
def pop(t):
if not t:
raise RuntimeError("cannot pop empty stack")
else:
return t(lambda next, v: (next, v))
def load(t, iterable):
for v in iterable:
t = push(t, v)
return t
def unload(t):
while t:
(next, v) = pop(t)
yield v
t = next
def reverse(t):
return load(empty, unload(t))
def peek(t):
if not t:
return None
else:
(_, v) = pop(t)
return v
class stack:
def empty(): return stack(empty)
def __init__(self, t): self.t = t
def push(self, v): return push(self.t, v)
def pop(self):
(next, v) = pop(self.t)
return (stack(next), v)
def load(self, iterable): return stack(load(self.t, iterable))
def unload(self): return unload(self.t)
def reverse(self): return stack(reverse(self.t))
def peek(self): return peek(self.t)
每个堆栈操作都会创建一个新堆栈,而不是使用.append、.pop 或.reverse 修改底层堆栈。如果我们愿意,请注意我们如何unload 两次(或更多)堆栈 -
from stack import stack
input = "we have not defeated corona"
s = stack.empty().load(input)
print("".join(s.unload()))
print("".join(s.reverse().unload()))
print("".join(s.unload()))
anoroc detaefed ton evah ew
we have not defeated corona
anoroc detaefed ton evah ew